File indexing completed on 2026-08-17 08:39:06
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef BOOST_BLOOM_DETAIL_FAST_MULTIBLOCK64_AVX2_HPP
0010 #define BOOST_BLOOM_DETAIL_FAST_MULTIBLOCK64_AVX2_HPP
0011
0012 #include <boost/bloom/detail/avx2.hpp>
0013 #include <boost/bloom/detail/multiblock_fpr_base.hpp>
0014 #include <boost/bloom/detail/mulx64.hpp>
0015 #include <boost/config.hpp>
0016 #include <boost/config/workaround.hpp>
0017 #include <cstddef>
0018 #include <cstdint>
0019
0020 namespace boost{
0021 namespace bloom{
0022
0023 #if defined(BOOST_MSVC)
0024 #pragma warning(push)
0025 #pragma warning(disable:4714)
0026 #endif
0027
0028 namespace detail{
0029
0030 struct m256ix2
0031 {
0032 __m256i lo,hi;
0033 };
0034
0035 }
0036
0037 template<std::size_t K>
0038 struct fast_multiblock64:detail::multiblock_fpr_base<K>
0039 {
0040 static constexpr std::size_t k=K;
0041 using value_type=detail::m256ix2[(k+7)/8];
0042 static constexpr std::size_t used_value_size=sizeof(std::uint64_t)*k;
0043
0044 static BOOST_FORCEINLINE void mark(value_type& x,std::uint64_t hash)
0045 {
0046 for(int i=0;i<k/8;++i){
0047 mark_m256ix2(x[i],hash,8);
0048 hash=detail::mulx64(hash);
0049 }
0050 if(k%8){
0051 mark_m256ix2(x[k/8],hash,k%8);
0052 }
0053 }
0054
0055 static BOOST_FORCEINLINE bool check(const value_type& x,std::uint64_t hash)
0056 {
0057 bool res=true;
0058 for(int i=0;i<k/8;++i){
0059 res&=check_m256ix2(x[i],hash,8);
0060 hash=detail::mulx64(hash);
0061 }
0062 if(k%8){
0063 res&=check_m256ix2(x[k/8],hash,k%8);
0064 }
0065 return res;
0066 }
0067
0068 private:
0069 static BOOST_FORCEINLINE detail::m256ix2 make_m256ix2(
0070 std::uint64_t hash,std::size_t kp)
0071 {
0072 const detail::m256ix2 ones[8]={
0073 {_mm256_set_epi64x(0,0,0,1),_mm256_set_epi64x(0,0,0,0)},
0074 {_mm256_set_epi64x(0,0,1,1),_mm256_set_epi64x(0,0,0,0)},
0075 {_mm256_set_epi64x(0,1,1,1),_mm256_set_epi64x(0,0,0,0)},
0076 {_mm256_set_epi64x(1,1,1,1),_mm256_set_epi64x(0,0,0,0)},
0077 {_mm256_set_epi64x(1,1,1,1),_mm256_set_epi64x(0,0,0,1)},
0078 {_mm256_set_epi64x(1,1,1,1),_mm256_set_epi64x(0,0,1,1)},
0079 {_mm256_set_epi64x(1,1,1,1),_mm256_set_epi64x(0,1,1,1)},
0080 {_mm256_set_epi64x(1,1,1,1),_mm256_set_epi64x(1,1,1,1)},
0081 };
0082
0083 __m256i h=_mm256_set1_epi64x(hash);
0084 h=_mm256_sllv_epi64(h,_mm256_set_epi64x(18,12,6,0));
0085 h=_mm256_srli_epi32(h,32-6);
0086 return {
0087 _mm256_sllv_epi64(
0088 ones[kp-1].lo,_mm256_cvtepu32_epi64(_mm256_extracti128_si256(h,0))),
0089 kp<=4?
0090 _mm256_set1_epi64x(0):
0091 _mm256_sllv_epi64(
0092 ones[kp-1].hi,_mm256_cvtepu32_epi64(_mm256_extracti128_si256(h,1)))
0093 };
0094 }
0095
0096 static BOOST_FORCEINLINE void mark_m256ix2(
0097 detail::m256ix2& x,std::uint64_t hash,std::size_t kp)
0098 {
0099 detail::m256ix2 h=make_m256ix2(hash,kp);
0100 x.lo=_mm256_or_si256(x.lo,h.lo);
0101 if(kp>4)x.hi=_mm256_or_si256(x.hi,h.hi);
0102 }
0103
0104 #if BOOST_WORKAROUND(BOOST_MSVC,<=1900)
0105
0106 #pragma warning(push)
0107 #pragma warning(disable:4800)
0108 #endif
0109
0110 static BOOST_FORCEINLINE bool check_m256ix2(
0111 const detail::m256ix2& x,std::uint64_t hash,std::size_t kp)
0112 {
0113 detail::m256ix2 h=make_m256ix2(hash,kp);
0114 auto res=_mm256_testc_si256(x.lo,h.lo);
0115 if(kp>4)res&=_mm256_testc_si256(x.hi,h.hi);
0116 return res;
0117 }
0118
0119 #if BOOST_WORKAROUND(BOOST_MSVC,<=1900)
0120 #pragma warning(pop)
0121 #endif
0122 };
0123
0124 #if defined(BOOST_MSVC)
0125 #pragma warning(pop)
0126 #endif
0127
0128 }
0129 }
0130
0131 #endif