-
Notifications
You must be signed in to change notification settings - Fork 3.4k
emmalloc: Fix allocations of high alignment #20704
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
Merged
Merged
Changes from all commits
Commits
Show all changes
13 commits
Select commit
Hold shift + click to select a range
73b1eda
fix
kripken cf5cb09
fix
kripken 5243c07
Merge remote-tracking branch 'origin/main' into emmalloc.high-align
kripken 87b24d7
code size improvements
kripken dfa2019
simplify
kripken a6c39ad
feedback
kripken c6aa7dc
feedback
kripken 630dfd1
Merge remote-tracking branch 'origin/main' into emmalloc.high-align
kripken c295958
oops
kripken 376ab0d
Merge remote-tracking branch 'origin/main' into emmalloc.high-align
kripken 3c800ab
fix
kripken 1caf4c1
rebaseline
kripken 4531bdd
update
kripken File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,10 @@ | ||
{ | ||
"a.html": 567, | ||
"a.html.gz": 379, | ||
"a.js": 17921, | ||
"a.js.gz": 8079, | ||
"a.js": 17841, | ||
"a.js.gz": 8088, | ||
"a.mem": 3171, | ||
"a.mem.gz": 2713, | ||
"total": 21659, | ||
"total_gz": 11171 | ||
"total": 21579, | ||
"total_gz": 11180 | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,10 @@ | ||
{ | ||
"a.html": 567, | ||
"a.html.gz": 379, | ||
"a.js": 17399, | ||
"a.js.gz": 7910, | ||
"a.js": 17319, | ||
"a.js.gz": 7908, | ||
"a.mem": 3171, | ||
"a.mem.gz": 2713, | ||
"total": 21137, | ||
"total_gz": 11002 | ||
"total": 21057, | ||
"total_gz": 11000 | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
#include <assert.h> | ||
#include <emscripten/console.h> | ||
#include <stdlib.h> | ||
#include <unistd.h> | ||
|
||
size_t sizeT(void* p) { | ||
return (size_t)p; | ||
} | ||
|
||
int main() { | ||
const size_t MB = 1024 * 1024; | ||
const size_t ALIGN = 4 * MB; | ||
const size_t SIZE = 32 * MB; | ||
|
||
// Allocate a very large chunk of memory (32MB) with very high alignment (4 | ||
// MB). This is similar to what mimalloc does in practice. | ||
void* before = sbrk(0); | ||
void* p = aligned_alloc(ALIGN, SIZE); | ||
void* after = sbrk(0); | ||
emscripten_console_logf("before: %p after: %p p: %p\n", before, after, p); | ||
|
||
// The allocation must be properly aligned. | ||
assert(sizeT(p) % ALIGN == 0); | ||
|
||
// We should only have sbrk'd a reasonable amount (this is a regression test | ||
// for #20645 where we sbrk'd double the necessary amount). We expect at most | ||
// 36 MB (the size of the allocation plus the alignment) plus a few bytes of | ||
// general overhead. | ||
assert(sizeT(after) - sizeT(before) < ALIGN + SIZE + 100); | ||
|
||
emscripten_console_log("success"); | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
success |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure I understand the status quo.. does did this work at all without this change?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It worked, but it would do the recursion in the earlier code twice. So it allocated a lot more than it needed, until it finally found enough room for the right size with the right allocation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wouldn't iteratively doing this actually use less memory in some cases? i.e. you could get lucky and get a good alignmenty without quite as much over allocation?
With this change are are guaranteed to waste alignment bytes on each allocation aren't we? In the mimalloc case that would be ~4Mb for each allocation. Or we we return the over-allocated chunk to the free list?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe we potentially reuse the extra space, Here is where the early unused space is added to the region before us:
emscripten/system/lib/emmalloc.c
Lines 604 to 617 in 87b24d7
Overall emmalloc's goal is to be compact and not the most optimal allocator, so I think this is a reasonable compromise. It's true that we might get lucky without this, as you said, and just happen to be aligned, but in large alignments that is less and less likely, and it's better to do the more straightforward and less risky thing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this we should wait for @juj to weigh in there.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Talking offline, @juj might not be available to review this for a bit and suggested it land for now if it is urgent, and be reviewed later. I think that makes sense as I'd like to get this in to avoid mimalloc using 2x the memory it needs to, in the first release with mimalloc. @sbc100 does that sound ok?