I want to overalign my type on a cache boundary, so I used alignas
:
struct alignas(64) W { };
This compiles fine. But then, to my surprise, when I try to allocate a bunch of W
s, they're not 64-byte aligned but actually 16-byte aligned:
#include <iostream>
#include <iomanip>
#include <unordered_map>
struct alignas(64) W { };
int main() {
std::unordered_map<int, int> offset;
for (int i = 0; i < 1000; ++i) {
auto w = new W;
offset[(uintptr_t)w % 64]++;
}
for (const auto& p : offset) {
std::cout << p.first << ' ' << p.second << '\n';
}
}
Yields:
0 250
16 250
32 250
48 250
on several compiles (gcc 4.8.2, gcc 5.2.0, clang 3.7.1). What's up? I told it to align, why isn't it aligning?
This is answered nicely here: https://stackoverflow.com/a/16510895
Basically: new
(at least in its normal usage) only guarantees a constant maximum alignment (alignof(std::max_align_t)
) for every call to new
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With