fast_multiblock32_avx2.hpp 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. /* Copyright 2025 Joaquin M Lopez Munoz.
  2. * Distributed under the Boost Software License, Version 1.0.
  3. * (See accompanying file LICENSE_1_0.txt or copy at
  4. * http://www.boost.org/LICENSE_1_0.txt)
  5. *
  6. * See https://www.boost.org/libs/bloom for library home page.
  7. */
  8. #ifndef BOOST_BLOOM_DETAIL_FAST_MULTIBLOCK32_AVX2_HPP
  9. #define BOOST_BLOOM_DETAIL_FAST_MULTIBLOCK32_AVX2_HPP
  10. #include <boost/bloom/detail/avx2.hpp>
  11. #include <boost/bloom/detail/multiblock_fpr_base.hpp>
  12. #include <boost/bloom/detail/mulx64.hpp>
  13. #include <boost/config.hpp>
  14. #include <boost/config/workaround.hpp>
  15. #include <cstddef>
  16. #include <cstdint>
  17. namespace boost{
  18. namespace bloom{
  19. #if defined(BOOST_MSVC)
  20. #pragma warning(push)
  21. #pragma warning(disable:4714) /* marked as __forceinline not inlined */
  22. #endif
  23. template<std::size_t K>
  24. struct fast_multiblock32:detail::multiblock_fpr_base<K>
  25. {
  26. static constexpr std::size_t k=K;
  27. using value_type=__m256i[(k+7)/8];
  28. static constexpr std::size_t used_value_size=sizeof(std::uint32_t)*k;
  29. static BOOST_FORCEINLINE void mark(value_type& x,std::uint64_t hash)
  30. {
  31. for(std::size_t i=0;i<k/8;++i){
  32. mark_m256i(x[i],hash,8);
  33. hash=detail::mulx64(hash);
  34. }
  35. if(k%8){
  36. mark_m256i(x[k/8],hash,k%8);
  37. }
  38. }
  39. static BOOST_FORCEINLINE bool check(const value_type& x,std::uint64_t hash)
  40. {
  41. bool res=true;
  42. for(std::size_t i=0;i<k/8;++i){
  43. res&=check_m256i(x[i],hash,8);
  44. hash=detail::mulx64(hash);
  45. }
  46. if(k%8){
  47. res&=check_m256i(x[k/8],hash,k%8);
  48. }
  49. return res;
  50. }
  51. private:
  52. static BOOST_FORCEINLINE __m256i make_m256i(
  53. std::uint64_t hash,std::size_t kp)
  54. {
  55. const __m256i ones[8]={
  56. _mm256_set_epi32(0,0,0,0,0,0,0,1),
  57. _mm256_set_epi32(0,0,0,0,0,0,1,1),
  58. _mm256_set_epi32(0,0,0,0,0,1,1,1),
  59. _mm256_set_epi32(0,0,0,0,1,1,1,1),
  60. _mm256_set_epi32(0,0,0,1,1,1,1,1),
  61. _mm256_set_epi32(0,0,1,1,1,1,1,1),
  62. _mm256_set_epi32(0,1,1,1,1,1,1,1),
  63. _mm256_set_epi32(1,1,1,1,1,1,1,1),
  64. };
  65. __m256i h=_mm256_set1_epi64x(hash);
  66. h=_mm256_sllv_epi64(h,_mm256_set_epi64x(15,10,5,0));
  67. h=_mm256_srli_epi32(h,32-5);
  68. return _mm256_sllv_epi32(ones[kp-1],h);
  69. }
  70. static BOOST_FORCEINLINE void mark_m256i(
  71. __m256i& x,std::uint64_t hash,std::size_t kp)
  72. {
  73. __m256i h=make_m256i(hash,kp);
  74. x=_mm256_or_si256(x,h);
  75. }
  76. #if BOOST_WORKAROUND(BOOST_MSVC,<=1900)
  77. /* 'int': forcing value to bool 'true' or 'false' */
  78. #pragma warning(push)
  79. #pragma warning(disable:4800)
  80. #endif
  81. static BOOST_FORCEINLINE bool check_m256i(
  82. const __m256i& x,std::uint64_t hash,std::size_t kp)
  83. {
  84. __m256i h=make_m256i(hash,kp);
  85. return _mm256_testc_si256(x,h);
  86. }
  87. #if BOOST_WORKAROUND(BOOST_MSVC,<=1900)
  88. #pragma warning(pop) /* C4800 */
  89. #endif
  90. };
  91. #if defined(BOOST_MSVC)
  92. #pragma warning(pop) /* C4714 */
  93. #endif
  94. } /* namespace bloom */
  95. } /* namespace boost */
  96. #endif