From 2fdc5182d6216f6c0b40349b64005dbef2c7d036 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Fri, 9 Dec 2022 11:35:35 +0200 Subject: [PATCH] Add xmx2_mix --- benchmark/uint32.cpp | 6 +++++- benchmark/uint64.cpp | 6 +++++- benchmark/uuid.cpp | 6 +++++- benchmark/word_size.cpp | 6 +++++- include/boost/unordered/detail/foa.hpp | 9 +++++++++ include/boost/unordered/detail/xmx.hpp | 25 +++++++++++++++++++++++++ 6 files changed, 54 insertions(+), 4 deletions(-) diff --git a/benchmark/uint32.cpp b/benchmark/uint32.cpp index 887ce727..d0f23d3e 100644 --- a/benchmark/uint32.cpp +++ b/benchmark/uint32.cpp @@ -292,6 +292,9 @@ template using boost_unordered_map = template using boost_unordered_flat_map_xmx = boost::unordered_flat_map, std::equal_to, allocator_for, boost::unordered::detail::foa::xmx_mix>; +template using boost_unordered_flat_map_xmx2 = + boost::unordered_flat_map, std::equal_to, allocator_for, boost::unordered::detail::foa::xmx2_mix>; + template using boost_unordered_flat_map_mulx = boost::unordered_flat_map, std::equal_to, allocator_for, boost::unordered::detail::foa::mulx_mix>; @@ -319,6 +322,7 @@ int main() test( "std::unordered_map" ); test( "boost::unordered_map" ); test( "boost::unordered_flat_map, xmx" ); + test( "boost::unordered_flat_map, xmx2" ); test( "boost::unordered_flat_map, mulx" ); #ifdef HAVE_ANKERL_UNORDERED_DENSE @@ -338,7 +342,7 @@ int main() for( auto const& x: times ) { - std::cout << std::setw( 33 ) << ( x.label_ + ": " ) << std::setw( 5 ) << x.time_ << " ms, " << std::setw( 9 ) << x.bytes_ << " bytes in " << x.count_ << " allocations\n"; + std::cout << std::setw( 34 ) << ( x.label_ + ": " ) << std::setw( 5 ) << x.time_ << " ms, " << std::setw( 9 ) << x.bytes_ << " bytes in " << x.count_ << " allocations\n"; } } diff --git a/benchmark/uint64.cpp b/benchmark/uint64.cpp index dd4faa57..c7765a8c 100644 --- a/benchmark/uint64.cpp +++ b/benchmark/uint64.cpp @@ -292,6 +292,9 @@ template using boost_unordered_map = template using boost_unordered_flat_map_xmx = boost::unordered_flat_map, std::equal_to, allocator_for, boost::unordered::detail::foa::xmx_mix>; +template using boost_unordered_flat_map_xmx2 = + boost::unordered_flat_map, std::equal_to, allocator_for, boost::unordered::detail::foa::xmx2_mix>; + template using boost_unordered_flat_map_mulx = boost::unordered_flat_map, std::equal_to, allocator_for, boost::unordered::detail::foa::mulx_mix>; @@ -329,6 +332,7 @@ int main() test( "boost::unordered_map" ); test( "boost::unordered_flat_map, xmx" ); + test( "boost::unordered_flat_map, xmx2" ); test( "boost::unordered_flat_map, mulx" ); #ifdef HAVE_ANKERL_UNORDERED_DENSE @@ -348,7 +352,7 @@ int main() for( auto const& x: times ) { - std::cout << std::setw( 33 ) << ( x.label_ + ": " ) << std::setw( 5 ) << x.time_ << " ms, " << std::setw( 9 ) << x.bytes_ << " bytes in " << x.count_ << " allocations\n"; + std::cout << std::setw( 34 ) << ( x.label_ + ": " ) << std::setw( 5 ) << x.time_ << " ms, " << std::setw( 9 ) << x.bytes_ << " bytes in " << x.count_ << " allocations\n"; } } diff --git a/benchmark/uuid.cpp b/benchmark/uuid.cpp index d89181f5..e201afae 100644 --- a/benchmark/uuid.cpp +++ b/benchmark/uuid.cpp @@ -343,6 +343,9 @@ template using boost_unordered_map = template using boost_unordered_flat_map_xmx = boost::unordered_flat_map, std::equal_to, allocator_for, boost::unordered::detail::foa::xmx_mix>; +template using boost_unordered_flat_map_xmx2 = + boost::unordered_flat_map, std::equal_to, allocator_for, boost::unordered::detail::foa::xmx2_mix>; + template using boost_unordered_flat_map_mulx = boost::unordered_flat_map, std::equal_to, allocator_for, boost::unordered::detail::foa::mulx_mix>; @@ -370,6 +373,7 @@ int main() test( "std::unordered_map" ); test( "boost::unordered_map" ); test( "boost::unordered_flat_map, xmx" ); + test( "boost::unordered_flat_map, xmx2" ); test( "boost::unordered_flat_map, mulx" ); #ifdef HAVE_ANKERL_UNORDERED_DENSE @@ -389,7 +393,7 @@ int main() for( auto const& x: times ) { - std::cout << std::setw( 33 ) << ( x.label_ + ": " ) << std::setw( 5 ) << x.time_ << " ms, " << std::setw( 9 ) << x.bytes_ << " bytes in " << x.count_ << " allocations\n"; + std::cout << std::setw( 34 ) << ( x.label_ + ": " ) << std::setw( 5 ) << x.time_ << " ms, " << std::setw( 9 ) << x.bytes_ << " bytes in " << x.count_ << " allocations\n"; } } diff --git a/benchmark/word_size.cpp b/benchmark/word_size.cpp index 433afb1d..2017776f 100644 --- a/benchmark/word_size.cpp +++ b/benchmark/word_size.cpp @@ -184,6 +184,9 @@ template using boost_unordered_map = template using boost_unordered_flat_map_xmx = boost::unordered_flat_map, std::equal_to, allocator_for, boost::unordered::detail::foa::xmx_mix>; +template using boost_unordered_flat_map_xmx2 = + boost::unordered_flat_map, std::equal_to, allocator_for, boost::unordered::detail::foa::xmx2_mix>; + template using boost_unordered_flat_map_mulx = boost::unordered_flat_map, std::equal_to, allocator_for, boost::unordered::detail::foa::mulx_mix>; @@ -211,6 +214,7 @@ int main() test( "std::unordered_map" ); test( "boost::unordered_map" ); test( "boost::unordered_flat_map, xmx" ); + test( "boost::unordered_flat_map, xmx2" ); test( "boost::unordered_flat_map, mulx" ); #ifdef HAVE_ANKERL_UNORDERED_DENSE @@ -230,7 +234,7 @@ int main() for( auto const& x: times ) { - std::cout << std::setw( 33 ) << ( x.label_ + ": " ) << std::setw( 5 ) << x.time_ << " ms, " << std::setw( 9 ) << x.bytes_ << " bytes in " << x.count_ << " allocations\n"; + std::cout << std::setw( 34 ) << ( x.label_ + ": " ) << std::setw( 5 ) << x.time_ << " ms, " << std::setw( 9 ) << x.bytes_ << " bytes in " << x.count_ << " allocations\n"; } } diff --git a/include/boost/unordered/detail/foa.hpp b/include/boost/unordered/detail/foa.hpp index 95c51bfd..8cb3f393 100644 --- a/include/boost/unordered/detail/foa.hpp +++ b/include/boost/unordered/detail/foa.hpp @@ -761,6 +761,15 @@ struct xmx_mix } }; +struct xmx2_mix +{ + template + static inline std::size_t mix(const Hash& h,const T& x) + { + return xmx2(h(x)); + } +}; + struct mulx_mix { template diff --git a/include/boost/unordered/detail/xmx.hpp b/include/boost/unordered/detail/xmx.hpp index 4b24fd80..d4c27434 100644 --- a/include/boost/unordered/detail/xmx.hpp +++ b/include/boost/unordered/detail/xmx.hpp @@ -64,6 +64,31 @@ static inline std::size_t xmx(std::size_t x)noexcept #endif } +// alternative multipliers + +static inline std::size_t xmx2( std::size_t x ) noexcept +{ +#if defined(BOOST_UNORDERED_64B_ARCHITECTURE) + + boost::uint64_t z=(boost::uint64_t)x; + + z ^= z >> 23; + z *= 0x9E3779B97F4A7C15ull; + z ^= z >> 23; + + return (std::size_t)z; + +#else /* 32 bits assumed */ + + x ^= x >> 18; + x *= 0x9E3779B9u; + x ^= x >> 16; + + return x; + +#endif +} + #ifdef BOOST_UNORDERED_64B_ARCHITECTURE #undef BOOST_UNORDERED_64B_ARCHITECTURE #endif