Hazard pointers: Add support for thread local lists of retired objects and other...
[folly.git] / folly / experimental / hazptr / bench / HazptrBench.h
index 097cd7f1e75c4f24874f9fb18f4c6c6f3f5fb842..2e49e348aa1bb666b3504ae9c8a584e8a5bd5c06 100644 (file)
 namespace folly {
 namespace hazptr {
 
-inline uint64_t run_once(int nthreads, int size, int ops) {
+template <typename InitFunc, typename Func, typename EndFunc>
+inline uint64_t run_once(
+    int nthreads,
+    const InitFunc& init,
+    const Func& fn,
+    const EndFunc& endFn) {
   folly::BenchmarkSuspender susp;
-  SWMRListSet<uint64_t> s;
   std::atomic<bool> start{false};
   std::atomic<int> started{0};
 
-  hazptr_holder dummy_hptr[100];
-
-  for (int i = 0; i < size; ++i) {
-    s.add(i);
-  }
+  init();
 
   std::vector<std::thread> threads(nthreads);
   for (int tid = 0; tid < nthreads; ++tid) {
@@ -45,10 +45,7 @@ inline uint64_t run_once(int nthreads, int size, int ops) {
       started.fetch_add(1);
       while (!start.load())
         /* spin */;
-
-      for (int j = tid; j < ops; j += nthreads) {
-        s.contains(j);
-      }
+      fn(tid);
     });
   }
 
@@ -67,20 +64,21 @@ inline uint64_t run_once(int nthreads, int size, int ops) {
   susp.rehire();
   // end time measurement
   auto tend = std::chrono::steady_clock::now();
+  endFn();
   return std::chrono::duration_cast<std::chrono::nanoseconds>(tend - tbegin)
       .count();
 }
 
-inline uint64_t bench(std::string name, int nthreads, int size, uint64_t base) {
+template <typename RepFunc>
+inline uint64_t bench(std::string name, int ops, const RepFunc& repFn) {
   int reps = 10;
-  int ops = 100000;
   uint64_t min = UINTMAX_MAX;
   uint64_t max = 0;
   uint64_t sum = 0;
 
-  run_once(nthreads, size, ops); // sometimes first run is outlier
+  repFn(); // sometimes first run is outlier
   for (int r = 0; r < reps; ++r) {
-    uint64_t dur = run_once(nthreads, size, ops);
+    uint64_t dur = repFn();
     sum += dur;
     min = std::min(min, dur);
     max = std::max(max, dur);
@@ -93,75 +91,221 @@ inline uint64_t bench(std::string name, int nthreads, int size, uint64_t base) {
   std::cout << "   " << std::setw(4) << max / ops << unit;
   std::cout << "   " << std::setw(4) << avg / ops << unit;
   std::cout << "   " << std::setw(4) << res / ops << unit;
-  if (base) {
-    std::cout << " " << std::setw(3) << 100 * base / res << "%";
-  }
   std::cout << std::endl;
   return res;
 }
 
+inline uint64_t listBench(std::string name, int nthreads, int size) {
+  int ops = 100000;
+  auto repFn = [&] {
+    hazptr_holder dummy[100];
+    SWMRListSet<uint64_t> s;
+    auto init = [&] {
+      for (int i = 0; i < size; ++i) {
+        s.add(i);
+      }
+    };
+    auto fn = [&](int tid) {
+      for (int j = tid; j < ops; j += nthreads) {
+        s.contains(size);
+      }
+    };
+    auto endFn = [] {};
+    return run_once(nthreads, init, fn, endFn);
+  };
+  return bench(name, ops, repFn);
+}
+
+inline uint64_t holderBench(std::string name, int nthreads) {
+  int ops = 100000;
+  auto repFn = [&] {
+    hazptr_holder dummy[100];
+    auto init = [] {};
+    auto fn = [&](int tid) {
+      for (int j = tid; j < ops; j += nthreads) {
+        hazptr_holder a[10];
+      }
+    };
+    auto endFn = [] {};
+    return run_once(nthreads, init, fn, endFn);
+  };
+  return bench(name, ops, repFn);
+}
+
+inline uint64_t retireBench(std::string name, int nthreads) {
+  struct Foo : hazptr_obj_base<Foo> {
+    int x;
+  };
+  int ops = 100000;
+  auto repFn = [&] {
+    hazptr_holder dummy[100];
+    auto init = [] {};
+    auto fn = [&](int tid) {
+      for (int j = tid; j < ops; j += nthreads) {
+        Foo* p = new Foo;
+        p->retire();
+      }
+    };
+    auto endFn = [] {};
+    return run_once(nthreads, init, fn, endFn);
+  };
+  return bench(name, ops, repFn);
+}
+
 const int nthr[] = {1, 10};
 const int sizes[] = {10, 100};
-const std::string header = "Test_name, Max time, Avg time, Min time";
 
-} // namespace folly {
+inline void benches(std::string name) {
+  std::cout << "------------------------------------------- " << name << "\n";
+  for (int i : nthr) {
+    std::cout << i << " threads -- construct/destruct 10 hazptr_holder-s"
+              << std::endl;
+    holderBench(name + "              ", i);
+    holderBench(name + " - dup        ", i);
+    std::cout << i << " threads -- allocate/retire/reclaim object" << std::endl;
+    retireBench(name + "              ", i);
+    retireBench(name + " - dup        ", i);
+    for (int j : sizes) {
+      std::cout << i << " threads -- " << j << "-item list" << std::endl;
+      listBench(name + "              ", i, j);
+      listBench(name + " - dup        ", i, j);
+    }
+  }
+  std::cout << "----------------------------------------------------------\n";
+}
+
 } // namespace hazptr {
+} // namespace folly {
 
 /*
-------------------------------------------- No AMB - No Tc
+------------------------------------------- no amb - no tc
+1 threads -- construct/destruct 10 hazptr_holder-s
+no amb - no tc                 2518 ns   2461 ns   2431 ns
+no amb - no tc - dup           2499 ns   2460 ns   2420 ns
+1 threads -- allocate/retire/reclaim object
+no amb - no tc                   85 ns     83 ns     81 ns
+no amb - no tc - dup             83 ns     82 ns     81 ns
+1 threads -- 10-item list
+no amb - no tc                  655 ns    644 ns    639 ns
+no amb - no tc - dup            658 ns    645 ns    641 ns
+1 threads -- 100-item list
+no amb - no tc                 2175 ns   2142 ns   2124 ns
+no amb - no tc - dup           2294 ns   2228 ns   2138 ns
+10 threads -- construct/destruct 10 hazptr_holder-s
+no amb - no tc                 3893 ns   2932 ns   1391 ns
+no amb - no tc - dup           3157 ns   2927 ns   2726 ns
+10 threads -- allocate/retire/reclaim object
+no amb - no tc                  152 ns    134 ns    127 ns
+no amb - no tc - dup            141 ns    133 ns    128 ns
+10 threads -- 10-item list
+no amb - no tc                  532 ns    328 ns    269 ns
+no amb - no tc - dup            597 ns    393 ns    271 ns
+10 threads -- 100-item list
+no amb - no tc                  757 ns    573 ns    412 ns
+no amb - no tc - dup            819 ns    643 ns    420 ns
+----------------------------------------------------------
+-------------------------------------------    amb - no tc
+1 threads -- construct/destruct 10 hazptr_holder-s
+   amb - no tc                 2590 ns   2481 ns   2422 ns
+   amb - no tc - dup           2519 ns   2468 ns   2424 ns
+1 threads -- allocate/retire/reclaim object
+   amb - no tc                   69 ns     68 ns     67 ns
+   amb - no tc - dup             69 ns     68 ns     67 ns
 1 threads -- 10-item list
-no amb - no tc                  713 ns    672 ns    648 ns
-no amb - no tc - dup            692 ns    660 ns    648 ns
+   amb - no tc                  524 ns    510 ns    492 ns
+   amb - no tc - dup            514 ns    507 ns    496 ns
 1 threads -- 100-item list
-no amb - no tc                 2167 ns   2146 ns   2133 ns
-no amb - no tc - dup           2210 ns   2153 ns   2133 ns
+   amb - no tc                  761 ns    711 ns    693 ns
+   amb - no tc - dup            717 ns    694 ns    684 ns
+10 threads -- construct/destruct 10 hazptr_holder-s
+   amb - no tc                 3302 ns   2908 ns   1612 ns
+   amb - no tc - dup           3220 ns   2909 ns   1641 ns
+10 threads -- allocate/retire/reclaim object
+   amb - no tc                  129 ns    123 ns    110 ns
+   amb - no tc - dup            135 ns    127 ns    120 ns
 10 threads -- 10-item list
-no amb - no tc                  716 ns    614 ns    285 ns
-no amb - no tc - dup            750 ns    546 ns    285 ns
+   amb - no tc                  512 ns    288 ns    256 ns
+   amb - no tc - dup            275 ns    269 ns    263 ns
 10 threads -- 100-item list
-no amb - no tc                 1923 ns   1482 ns    862 ns
-no amb - no tc - dup           1978 ns   1614 ns   1112 ns
+   amb - no tc                  297 ns    289 ns    284 ns
+   amb - no tc - dup            551 ns    358 ns    282 ns
 ----------------------------------------------------------
----------------------------------------------- AMB - No TC
+------------------------------------------- no amb -    tc
+1 threads -- construct/destruct 10 hazptr_holder-s
+no amb -    tc                   56 ns     55 ns     55 ns
+no amb -    tc - dup             56 ns     54 ns     54 ns
+1 threads -- allocate/retire/reclaim object
+no amb -    tc                   63 ns     62 ns     62 ns
+no amb -    tc - dup             64 ns     63 ns     62 ns
 1 threads -- 10-item list
-amb - no tc                     519 ns    504 ns    501 ns
-amb - no tc - dup               533 ns    511 ns    500 ns
+no amb -    tc                  190 ns    188 ns    187 ns
+no amb -    tc - dup            193 ns    186 ns    182 ns
 1 threads -- 100-item list
-amb - no tc                     721 ns    696 ns    689 ns
-amb - no tc - dup               786 ns    718 ns    688 ns
+no amb -    tc                 1859 ns   1698 ns   1666 ns
+no amb -    tc - dup           1770 ns   1717 ns   1673 ns
+10 threads -- construct/destruct 10 hazptr_holder-s
+no amb -    tc                   19 ns     11 ns      7 ns
+no amb -    tc - dup             11 ns      8 ns      7 ns
+10 threads -- allocate/retire/reclaim object
+no amb -    tc                    9 ns      8 ns      8 ns
+no amb -    tc - dup             10 ns      9 ns      8 ns
 10 threads -- 10-item list
-amb - no tc                     695 ns    565 ns    380 ns
-amb - no tc - dup               710 ns    450 ns    242 ns
+no amb -    tc                   40 ns     25 ns     21 ns
+no amb -    tc - dup             24 ns     23 ns     21 ns
 10 threads -- 100-item list
-amb - no tc                     921 ns    773 ns    573 ns
-amb - no tc - dup               594 ns    441 ns    409 ns
+no amb -    tc                  215 ns    208 ns    188 ns
+no amb -    tc - dup            215 ns    209 ns    197 ns
 ----------------------------------------------------------
----------------------------------------------- No AMB - TC
+-------------------------------------------    amb -    tc
+1 threads -- construct/destruct 10 hazptr_holder-s
+   amb -    tc                   56 ns     54 ns     54 ns
+   amb -    tc - dup             55 ns     54 ns     53 ns
+1 threads -- allocate/retire/reclaim object
+   amb -    tc                   62 ns     61 ns     61 ns
+   amb -    tc - dup             62 ns     61 ns     61 ns
 1 threads -- 10-item list
-no amb - tc                     182 ns    180 ns    178 ns
-no amb - tc - dup               205 ns    183 ns    178 ns
+   amb -    tc                   36 ns     35 ns     33 ns
+   amb -    tc - dup             37 ns     35 ns     34 ns
 1 threads -- 100-item list
-no amb - tc                    1756 ns   1697 ns   1670 ns
-no amb - tc - dup              1718 ns   1681 ns   1666 ns
+   amb -    tc                  262 ns    247 ns    230 ns
+   amb -    tc - dup            249 ns    238 ns    230 ns
+10 threads -- construct/destruct 10 hazptr_holder-s
+   amb -    tc                   14 ns     12 ns     11 ns
+   amb -    tc - dup             12 ns     11 ns     11 ns
+10 threads -- allocate/retire/reclaim object
+   amb -    tc                   18 ns     17 ns     15 ns
+   amb -    tc - dup             18 ns     17 ns     15 ns
 10 threads -- 10-item list
-no amb - tc                     174 ns    120 ns     55 ns
-no amb - tc - dup               174 ns    143 ns    114 ns
+   amb -    tc                    9 ns      8 ns      8 ns
+   amb -    tc - dup              8 ns      8 ns      7 ns
 10 threads -- 100-item list
-no amb - tc                    1480 ns   1058 ns    565 ns
-no amb - tc - dup              1834 ns   1327 ns   1065 ns
+   amb -    tc                   52 ns     42 ns     28 ns
+   amb -    tc - dup             44 ns     37 ns     28 ns
 ----------------------------------------------------------
-------------------------------------------------- AMB - TC
+-------------------------------------------     one domain
+1 threads -- construct/destruct 10 hazptr_holder-s
+    one domain                   57 ns     56 ns     55 ns
+    one domain - dup             56 ns     54 ns     53 ns
+1 threads -- allocate/retire/reclaim object
+    one domain                   87 ns     71 ns     64 ns
+    one domain - dup             69 ns     68 ns     68 ns
 1 threads -- 10-item list
-amb - tc                         32 ns     32 ns     31 ns
-amb - tc - dup                   32 ns     32 ns     31 ns
+    one domain                   32 ns     30 ns     29 ns
+    one domain - dup             31 ns     30 ns     29 ns
 1 threads -- 100-item list
-amb - tc                        238 ns    229 ns    221 ns
-amb - tc - dup                  224 ns    222 ns    221 ns
+    one domain                  269 ns    238 ns    226 ns
+    one domain - dup            237 ns    232 ns    227 ns
+10 threads -- construct/destruct 10 hazptr_holder-s
+    one domain                   16 ns     12 ns     10 ns
+    one domain - dup             11 ns     10 ns     10 ns
+10 threads -- allocate/retire/reclaim object
+    one domain                   19 ns     17 ns     16 ns
+    one domain - dup             19 ns     17 ns     15 ns
 10 threads -- 10-item list
-amb - tc                         27 ns     20 ns     13 ns
-amb - tc - dup                   28 ns     22 ns     18 ns
+    one domain                    6 ns      5 ns      5 ns
+    one domain - dup              6 ns      5 ns      5 ns
 10 threads -- 100-item list
-amb - tc                        221 ns    165 ns    116 ns
-amb - tc - dup                  277 ns    169 ns    120 ns
+    one domain                   40 ns     39 ns     35 ns
+    one domain - dup             40 ns     39 ns     35 ns
 ----------------------------------------------------------
  */