-
Notifications
You must be signed in to change notification settings - Fork 276
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
cacheint, spinlock instances not necessarily 64-byte aligned #53
Comments
Yes this is definitely an issue! Now that the container is allocator-aware, I'm a bit reluctant to impose an aligned allocator on top of that, because if somebody does pass in an aligned-allocator, we'll be double-aligning each time. Also, I think this issue will be resolved in C++17, because new and delete will do over-aligned allocations properly. Perhaps it's worth adding a warning to the documentation that the table makes use of over-aligned types so it's recommended to pass in an aligned allocator like the boost one. |
I also observe a significant performance degradation (especially in simple tests) in a benchmark: spinlock with alignas(64):
spinlock without alignas(64):
|
This is still an issue, triggering UBSAN warnings as shown in #97. Note that I'm compiling with C++17, yet the issue is still there and not resolved. The documentation of libcuckoo says:
Yet even when I specify
How is this supposed to work? |
Hmm this is pretty odd - https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65122 claims this should work with GCC 7 onwards, and I'm already using 11.1, yet it still doesn't work. |
OK, I think this isn't really related to libcuckoo, but rather an issue with the compilers or C++ as a language. This is enough to trigger the warnings:
Basically it looks like emplace_back does not work correctly. Resize on the other hand seems to work: https://godbolt.org/z/o4qGWravq |
Do not create `spinlock()` default arguments when initializing locks_t. Instead, use the two-arg std::vector constructor which will do the same in-place. This work-arounds the UBSAN alignment warnings such as: ``` libcuckoo/libcuckoo/cuckoohash_map.hh:805:18: runtime error: member access within misaligned address 0x7f5343f9a6a0 for type 'struct spinlock', which requires 64 byte alignment 0x7f5343f9a6a0: note: pointer points here 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ^ #0 0x7f5373045890 in libcuckoo::cuckoohash_map<...>::spinlock::spinlock() .../libcuckoo/libcuckoo/cuckoohash_map.hh:805 efficient#1 0x7f5373043ef2 in libcuckoo::cuckoohash_map<...>::cuckoohash_map(unsigned long, std::hash<QString> const&, std::equal_to<QString> const&, boost::alignment::aligned_allocator<std::pair<QString const, ImageIO::OnDiskStringCache::InternedString>, 64ul> const&) /home/milian/projects/kdab/qitissue/KDAB/io/../../3rdParty/libcuckoo/libcuckoo/cuckoohash_map.hh:116 ``` Fixes: efficient#53
Do not create `spinlock()` default arguments when initializing locks_t. Instead, use the two-arg std::vector constructor which will do the same in-place. This work-arounds the UBSAN alignment warnings such as: ``` libcuckoo/libcuckoo/cuckoohash_map.hh:805:18: runtime error: member access within misaligned address 0x7f5343f9a6a0 for type 'struct spinlock', which requires 64 byte alignment 0x7f5343f9a6a0: note: pointer points here 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ^ #0 0x7f5373045890 in libcuckoo::cuckoohash_map<...>::spinlock::spinlock() .../libcuckoo/libcuckoo/cuckoohash_map.hh:805 efficient#1 0x7f5373043ef2 in libcuckoo::cuckoohash_map<...>::cuckoohash_map(unsigned long, std::hash<QString> const&, std::equal_to<QString> const&, boost::alignment::aligned_allocator<std::pair<QString const, ImageIO::OnDiskStringCache::InternedString>, 64ul> const&) /home/milian/projects/kdab/qitissue/KDAB/io/../../3rdParty/libcuckoo/libcuckoo/cuckoohash_map.hh:116 ``` Fixes: efficient#53
libcuckoo tags the definitions of the
cacheint
andspinlock
classes withalignas(64)
/__attribute__((aligned(64)))
, presumably to avoid false sharing. However it goes on to use these classes in containers likestd::vector
andlazy_array
. AFAIK thestd::vector
from libstdc++ or MSVC will not respect the alignment of its containing elements, andlazy_array
doesn't seem to either. Thealignas
here ensures that elements are spaced 64-bytes apart, but doesn't ensure they're aligned on 64-byte boundaries.You may want to consider writing a custom allocator that has support for over-aligned allocations and using it for these containers. The
aligned_allocator_adaptor
from Boost gives an example.The text was updated successfully, but these errors were encountered: