3 ms·
One thing you can run into with these types in C/C++ is that the compiler assumes these types are aligned (unless you use some specific compiler attributes) and
by loeg 3y ago
One thing you can run into with these types in C/C++ is that the compiler assumes these types are aligned (unless you use some specific compiler attributes) and generates accesses that require alignment (e.g. MOVDQA) instead of ones that don't (MOVDQU). This is problematic if you have some custom allocator that (incorrectly) only provides 8-byte alignment, and cast allocated pointers to pointers to this 16-byte type (or a struct containing it). Not a Rust problem at all, just something to be careful of.
I found the LLVM/Clang bugs mentioned in the article kind of fascinating. As far as I know Clang has supported these types (partially) for quite a long time, so it's interesting that these issues weren't fixed until quite recently (if at all?).
- acuozzo 3y agoAre there instances of compilers with targets having both 128-bit ints and alignof(max_align_t) != 16? I'm asking because I can't imagine writing a custom allocator against anything other than alignof(max_align_t). Unless you're solely targeting <= C99… why use anything else?
- tlb 3y agoYes: OSX on ARM64 has alignof(max_align_t)==8 and alignof(__int128)==16. And malloc only provides 8-byte alignment, so if you're using types that require 16-byte alignment, you have to call aligned_alloc. Also, the stack is only 8-byte aligned. Despite the alignof, int128 doesn't actually require 16-byte alignment on ARM64, so nothing goes wrong when you have an int128 within an 8-byte aligned struct. Some x86-64 SIMD types do require 16-byte alignment (depending on what instructions you load them with). The Eigen math library, for instance, is slightly faster when you tell it to assume everything is 16-byte aligned, but you have to do some work to guarantee that's true. As well as calling aligned_alloc, you have to avoid locals since the stack is only 8-byte aligned.
- stephencanon 3y ago> Yes: OSX on ARM64 has alignof(max_align_t)==8 and alignof(__int128)==16. And malloc only provides 8-byte alignment, so if you're using types that require 16-byte alignment, you have to call aligned_alloc. Also, the stack is only 8-byte aligned. Huh? Stack alignment is 16B ("The stack pointer on Apple platforms follows the ARM64 standard ABI and requires 16-byte alignment." https://developer.apple.com/documentation/xcode/writing-arm64-code-for-apple-platforms https://developer.apple.com/documentation/xcode/writing-arm6...) and memory returned by the system malloc is always 16B aligned (it was 16B aligned even on 32b x86 and ARM).
- tlb 3y agoYou are correct. I think I was misremembering problems caused by SIMD types that require 32- or 64-byte alignment.