-
Notifications
You must be signed in to change notification settings - Fork 1.4k
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
What are malloc's alignment guarantees? #1533
Comments
The (non-alignment-specifying) allocation functions return memory aligned for any type of object that can live in the returned space. Practically, this means an alignment of 8 for 8-byte allocations, and 16 for 16-or-more-byte allocations, on 64-bit systems. (This can be tweaked as a config option, as well). |
After some more chatting with @gnzlbg, I think I understand better now why I feel that there is a gap in the docs here. You are specifically talking about types and objects in C here. In Rust, we support allocations (but not types) where
EDIT: Sorry I misread. I assume you mean in general "alignment N for N-byte allocations" when N is a power of two. What about non-powers-of-two? I expect it's something like "N rounded down to the next power of 2"? |
It was "obvious" to me that, since Interpreting the guarantees from the C standard isn't trivial, and extracting the precise guarantees from platforms ABI documents is hard. I will send a PR documenting this, and showing an example for, e.g., SysV64. This will need a bit of iteration to make sure that we only guarantee what we are allowed to guarantee, so that we do not limit platform compatibility, configurability, optimization opportunities, etc. About The standard APIs that do support an alignment argument, That kind of leaves the non-standard jemalloc-specific APIs which support an alignment request via the
For example, when one wants to perform a 2 byte sized allocation with an alignment of 4, such that I think that this behavior should be called out explicitly. |
Thanks!
Both seem fairly clear in the documentation. However, I can't tell if there are any other extra assumptions they might be making that are not mentioned. What about There is a curious difference between "must be" and "behavior is undefined"; my assumption would be that a violation of a "must" clause also causes UB? |
See #1277 . |
See the
|
Note that this bug has been fixed recently upstream because it made glibc's malloc incompatible with gcc, e.g., see also https://sourceware.org/bugzilla/show_bug.cgi?id=21120 . |
Yeah, basically that but for |
The behavior is the same for all C standard APIs, so the behavior of EDIT: Actually POSIX:2018 improves on this, guaranteeing the same behavior as C:
So AFAICT this means that allocating zero size cannot ever return error, since there is always sufficient memory to store zero bytes. |
You consider it clear. ;)
I did not know that |
It violates the new LLVM 13 clang's assumption of This actually caused a crash in firefox due to unaligned access when using LLVM 13 and jemalloc together, see |
Thanks! Replying upstream. |
LLVM upstream's take on this is that the glibc malloc behavior of 16-byte alignment is a platform guarantee for anything targeting From what I know of the runtime upstream I don't actually think this is a correct interpretation (I read it as information about the default alignment rather than a contract; other parts of the stdlib distribution avoid making similar assumptions, and from what I know of the glibc malloc maintainers they're fairly live-and-let-live in terms of the constraints they try to impose on malloc replacements), but for a combination of me being on parental leave / my job can easily work around the perf regression via compiler flags / upstream doesn't agree about it, I'm not super motivated to argue about it further. For us going forward, I think just disabling sub-quantum size classes might be easiest. So long as the config setting stays around it's still semi-opt-in, just with some more coordination required. |
Hello. What about 32bit systems? Is it possible to use lg-quantum=2 and what are the size classes with lg-quantum 2, 3 and 4? I'm guessing here so please correct me if I'm wrong:
|
Practically, SC_LG_TINY_MIN is a floor on lg-quantum and is unconfigurably set to 3. I think it might be possible to set lg-quantum below this, but I wouldn't expect things to work correctly -- the size class computation logic has this as a built-in assumption. |
The AVFrame deinterlacer is used by mytharchivehelper to create thumbnail images. In commit bb6365f the code has been updated to use the MythVideoFrame deinterlacer; previously a local implementation was used. This commit introduced an error in the conversion from AVFrame to MythVideoFrame. MythVideoFrame expects the video data to be stored in a contiguous memory area, with one base pointer and various offsets pointing to the different areas (Y, U, V). AVFrame has three pointers and can and does use separate memory areas. The original code used pointer subtractions to compute the offsets for MythVideoFrame but this only works if the video memory is one contigous memory area. If not, it leads to segfaults. This is now fixed by copying the AVFrame video data into a temporary buffer and passing that to the deinterlacer. Note that commit bb6365f has not been reverted because the MythVideoFrame deinterlacer gives a better picture quality than the original AVFrame deinterlacer. Thanks to @bshanteau for reporting the problem. Thanks to @rcrdnalor for analyzing the problem. Refs #633 (cherry picked from commit d8976e5)
Is it possible to configure jemalloc (5.3.0) so that it always returns 16-byte aligned addresses, even for requests of size <= 8? I'm running into an issue with a 3rd-party library on Linux that assumes all heap pointers are 16-byte aligned. I'm using lg-quantum=4, but jemalloc will return 8-byte aligned addresses for sizes <= 8. |
What exactly are the guarantees that jemalloc's
malloc
provides in terms of alignment?The docs say
However, in rust-lang/rust#45955 we noticed that this is not correct: at least with GCC/clang extensions, one can define a type of size 8 that has alignment 16. However, jemalloc has been observed handing out allocations of size 8 that are just 8-aligned.
System allocator functions usually seem to guarantee that everything is at least 16-byte aligned on an x86-64 system -- at least that's what comments in the Rust source say, but I do not know where that information is coming from. However, jemalloc violates that expectation. It would be useful to know what exactly is guaranteed in terms of alignment for small allocations (including small non-power-of-2 allocations).
EDIT: This value of 16 seems to originate from https://www.gnu.org/software/libc/manual/html_node/Aligned-Memory-Blocks.html#Aligned-Memory-Blocks (Ctrl-F "sixteen"). Of course that is not normative for jemalloc, but it will catch applications by surprise when jemalloc is used as a drop-in replacement.
The text was updated successfully, but these errors were encountered: