]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
common/bloom_filter: use popcount() to implement density()
authorKefu Chai <kchai@redhat.com>
Tue, 27 Jul 2021 06:58:01 +0000 (14:58 +0800)
committerKefu Chai <kchai@redhat.com>
Tue, 27 Jul 2021 12:03:32 +0000 (20:03 +0800)
instead of counting the bits using a loop, it'd be more efficient to do
this using the SIMD instruction.

Signed-off-by: Kefu Chai <kchai@redhat.com>
src/common/bloom_filter.hpp

index ff6f707566f923bb895ef3ec8ce85005796de80e..3e75e4e60a7baa960fcf8b626b9597e5d2a90827 100644 (file)
 #define COMMON_BLOOM_FILTER_HPP
 
 #include <cmath>
+#include <numeric>
 
-#include "include/mempool.h"
 #include "include/encoding.h"
+#include "include/intarith.h"
+#include "include/mempool.h"
 
 static const unsigned char bit_mask[CHAR_BIT] = {
   0x01,  //00000001
@@ -277,16 +279,12 @@ public:
    */
   inline double density() const
   {
-    size_t set = 0;
-    auto p = bit_table_.begin();
-    size_t left = table_size_;
-    while (left-- > 0) {
-      uint8_t c = *p;
-      for (; c; ++set)
-       c &= c - 1;
-      ++p;
-    }
-    return (double)set / (double)(table_size_ << 3);
+    unsigned set = std::transform_reduce(
+      bit_table_.begin(),
+      bit_table_.begin() + table_size_,
+      0, std::plus<>(),
+      popcount<cell_type>);
+    return (double)set / (table_size_ * sizeof(cell_type) * CHAR_BIT);
   }
 
   virtual inline double approx_unique_element_count() const {