Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a better brk() test, from Matthew Wilcox #31

Merged
merged 1 commit into from Jan 11, 2021
Merged

Conversation

antonblanchard
Copy link
Owner

The gory details from Willy:

Linux has this horrendously complicated anon_vma structure that you don't
care about, but the upshot is that after calling fork(), each process
that calls brk() gets a new VMA created. That is, after calling brk()
the first time, the process address space looks like this:

557777fab000-557777ff0000 rw-p 00000000 00:00 0 [heap]
557777ff0000-557777ff1000 rw-p 00000000 00:00 0 [heap]

so what brk1 is actually testing is how long it takes to create & destroy
a new VMA. This does not match what most programs do -- most will call
exec() which resets the anon_vma structures and starts each program off
with its own heap. And if you do have a multi-process program which
uses brk(), chances are it doesn't just oscillate betwee zero and one
extra pages of heap compared to its parent.

A better test starts out by allocating one page on the heap and then
throbs between one and two pages instead of throbbing between zero and
one page. That means we're actually testing expanding and contracting
the heap instead of creating and destroying a new heap.

For realism, I wanted to add actually accessing the memory in the new
heap, but that doesn't work for the threaded case -- another thread
might remove the memory you just allocated while you're allocating it.
Threaded programs give each thread its own heap anyway, so this is
kind of a pointless syscall to ask about its threaded scalability.

Anyway, here's brk2.c. It is not very different from brk1.c, but the
performance results are quite different (actually worse by about 10-15%).

Signed-off-by: Anton Blanchard anton@ozlabs.org

The gory details from Willy:

Linux has this horrendously complicated anon_vma structure that you don't
care about, but the upshot is that after calling fork(), each process
that calls brk() gets a _new_ VMA created.  That is, after calling brk()
the first time, the process address space looks like this:

557777fab000-557777ff0000 rw-p 00000000 00:00 0                          [heap]
557777ff0000-557777ff1000 rw-p 00000000 00:00 0                          [heap]

so what brk1 is actually testing is how long it takes to create & destroy
a new VMA.  This does not match what most programs do -- most will call
exec() which resets the anon_vma structures and starts each program off
with its own heap.  And if you do have a multi-process program which
uses brk(), chances are it doesn't just oscillate betwee zero and one
extra pages of heap compared to its parent.

A better test starts out by allocating one page on the heap and then
throbs between one and two pages instead of throbbing between zero and
one page.  That means we're actually testing expanding and contracting
the heap instead of creating and destroying a new heap.

For realism, I wanted to add actually accessing the memory in the new
heap, but that doesn't work for the threaded case -- another thread
might remove the memory you just allocated while you're allocating it.
Threaded programs give each thread its own heap anyway, so this is
kind of a pointless syscall to ask about its threaded scalability.

Anyway, here's brk2.c.  It is not very different from brk1.c, but the
performance results are quite different (actually worse by about 10-15%).

Signed-off-by: Anton Blanchard <anton@ozlabs.org>
@antonblanchard antonblanchard merged commit a34a85c into master Jan 11, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

1 participant