Futex::futexWait returns FutexResult
[folly.git] / folly / test / BenchmarkTest.cpp
index 9bd0015929d5069ad4f9f4466fee94449b4be75a..b876be2d3ade02801f2594232e4505d5cb8e3663 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2014 Facebook, Inc.
+ * Copyright 2017 Facebook, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * limitations under the License.
  */
 
-#include "folly/Benchmark.h"
-#include "folly/Foreach.h"
-#include "folly/String.h"
+#include <folly/Benchmark.h>
+#include <folly/String.h>
+#include <folly/container/Foreach.h>
+#include <algorithm>
 #include <iostream>
+#include <numeric>
+#include <random>
+#include <vector>
 using namespace folly;
 using namespace std;
 
@@ -42,6 +46,202 @@ BENCHMARK(gun) {
 
 BENCHMARK_DRAW_LINE()
 
+BENCHMARK(optimizerCanDiscardTrivial, n) {
+  long x = 0;
+  for (long i = 0; i < n; ++i) {
+    for (long j = 0; j < 10000; ++j) {
+      x += j;
+    }
+  }
+}
+
+BENCHMARK(optimizerCanPowerReduceInner1Trivial, n) {
+  long x = 0;
+  for (long i = 0; i < n; ++i) {
+    for (long j = 0; j < 10000; ++j) {
+      x += i + j;
+    }
+    doNotOptimizeAway(x);
+  }
+}
+
+BENCHMARK(optimizerCanPowerReduceInner2Trivial, n) {
+  long x = 0;
+  for (long i = 0; i < n; ++i) {
+    makeUnpredictable(i);
+    for (long j = 0; j < 10000; ++j) {
+      x += i + j;
+    }
+  }
+  doNotOptimizeAway(x);
+}
+
+BENCHMARK(optimizerDisabled1Trivial, n) {
+  long x = 0;
+  for (long i = 0; i < n; ++i) {
+    for (long j = 0; j < 10000; ++j) {
+      x += i + j;
+      doNotOptimizeAway(x);
+    }
+  }
+}
+
+BENCHMARK(optimizerDisabled2Trivial, n) {
+  long x = 0;
+  for (long i = 0; i < n; ++i) {
+    makeUnpredictable(i);
+    for (long j = 0; j < 10000; ++j) {
+      makeUnpredictable(j);
+      x += i + j;
+    }
+  }
+  doNotOptimizeAway(x);
+}
+
+BENCHMARK(optimizerCanPowerReduceInner1TrivialPtr, n) {
+  long x = 0;
+  for (long i = 0; i < n; ++i) {
+    for (long j = 0; j < 10000; ++j) {
+      x += i + j;
+    }
+    doNotOptimizeAway(&x);
+  }
+}
+
+BENCHMARK(optimizerCanPowerReduceInner2TrivialPtr, n) {
+  long x = 0;
+  for (long i = 0; i < n; ++i) {
+    makeUnpredictable(i);
+    for (long j = 0; j < 10000; ++j) {
+      x += i + j;
+    }
+  }
+  doNotOptimizeAway(&x);
+}
+
+BENCHMARK(optimizerDisabled1TrivialPtr, n) {
+  long x = 0;
+  for (long i = 0; i < n; ++i) {
+    for (long j = 0; j < 10000; ++j) {
+      x += i + j;
+      doNotOptimizeAway(&x);
+    }
+  }
+}
+
+namespace {
+class NonTrivialLong {
+ public:
+  explicit NonTrivialLong(long v) : value_(v) {}
+  virtual ~NonTrivialLong() {}
+
+  void operator++() {
+    ++value_;
+  }
+  void operator+=(long rhs) {
+    value_ += rhs;
+  }
+  void operator+=(const NonTrivialLong& rhs) {
+    value_ += rhs.value_;
+  }
+  bool operator<(long rhs) {
+    return value_ < rhs;
+  }
+  NonTrivialLong operator+(const NonTrivialLong& rhs) {
+    return NonTrivialLong(value_ + rhs.value_);
+  }
+
+ private:
+  long value_;
+  long otherStuff_[3];
+};
+} // namespace
+
+BENCHMARK(optimizerCanDiscardNonTrivial, n) {
+  NonTrivialLong x(0);
+  for (NonTrivialLong i(0); i < n; ++i) {
+    for (NonTrivialLong j(0); j < 10000; ++j) {
+      x += j;
+    }
+  }
+}
+
+BENCHMARK(optimizerCanPowerReduceInner1NonTrivial, n) {
+  NonTrivialLong x(0);
+  for (NonTrivialLong i(0); i < n; ++i) {
+    for (NonTrivialLong j(0); j < 10000; ++j) {
+      x += i + j;
+    }
+    doNotOptimizeAway(x);
+  }
+}
+
+BENCHMARK(optimizerCanPowerReduceInner2NonTrivial, n) {
+  NonTrivialLong x(0);
+  for (NonTrivialLong i(0); i < n; ++i) {
+    makeUnpredictable(i);
+    for (NonTrivialLong j(0); j < 10000; ++j) {
+      x += i + j;
+    }
+  }
+  doNotOptimizeAway(x);
+}
+
+BENCHMARK(optimizerDisabled1NonTrivial, n) {
+  NonTrivialLong x(0);
+  for (NonTrivialLong i(0); i < n; ++i) {
+    for (NonTrivialLong j(0); j < 10000; ++j) {
+      x += i + j;
+      doNotOptimizeAway(x);
+    }
+  }
+}
+
+BENCHMARK(optimizerDisabled2NonTrivial, n) {
+  NonTrivialLong x(0);
+  for (NonTrivialLong i(0); i < n; ++i) {
+    makeUnpredictable(i);
+    for (NonTrivialLong j(0); j < 10000; ++j) {
+      makeUnpredictable(j);
+      x += i + j;
+    }
+  }
+  doNotOptimizeAway(x);
+}
+
+BENCHMARK(optimizerCanPowerReduceInner1NonTrivialPtr, n) {
+  NonTrivialLong x(0);
+  for (NonTrivialLong i(0); i < n; ++i) {
+    for (NonTrivialLong j(0); j < 10000; ++j) {
+      x += i + j;
+    }
+    doNotOptimizeAway(&x);
+  }
+}
+
+BENCHMARK(optimizerCanPowerReduceInner2NonTrivialPtr, n) {
+  NonTrivialLong x(0);
+  for (NonTrivialLong i(0); i < n; ++i) {
+    makeUnpredictable(i);
+    for (NonTrivialLong j(0); j < 10000; ++j) {
+      x += i + j;
+    }
+  }
+  doNotOptimizeAway(&x);
+}
+
+BENCHMARK(optimizerDisabled1NonTrivialPtr, n) {
+  NonTrivialLong x(0);
+  for (NonTrivialLong i(0); i < n; ++i) {
+    for (NonTrivialLong j(0); j < 10000; ++j) {
+      x += i + j;
+      doNotOptimizeAway(&x);
+    }
+  }
+}
+
+BENCHMARK_DRAW_LINE()
+
 BENCHMARK(baselinevector) {
   vector<int> v;
 
@@ -67,8 +267,101 @@ BENCHMARK(superslow) {
   sleep(1);
 }
 
+BENCHMARK_DRAW_LINE()
+
+BENCHMARK(noMulti) {
+  fun();
+}
+
+BENCHMARK_MULTI(multiSimple) {
+  FOR_EACH_RANGE (i, 0, 10) {
+    fun();
+  }
+  return 10;
+}
+
+BENCHMARK_RELATIVE_MULTI(multiSimpleRel) {
+  FOR_EACH_RANGE (i, 0, 10) {
+    fun();
+    fun();
+  }
+  return 10;
+}
+
+BENCHMARK_MULTI(multiIterArgs, iter) {
+  FOR_EACH_RANGE (i, 0, 10 * iter) {
+    fun();
+  }
+  return 10 * iter;
+}
+
+BENCHMARK_RELATIVE_MULTI(multiIterArgsRel, iter) {
+  FOR_EACH_RANGE (i, 0, 10 * iter) {
+    fun();
+    fun();
+  }
+  return 10 * iter;
+}
+
+unsigned paramMulti(unsigned iter, unsigned num) {
+  for (unsigned i = 0; i < iter; ++i) {
+    for (unsigned j = 0; j < num; ++j) {
+      fun();
+    }
+  }
+  return num * iter;
+}
+
+unsigned paramMultiRel(unsigned iter, unsigned num) {
+  for (unsigned i = 0; i < iter; ++i) {
+    for (unsigned j = 0; j < num; ++j) {
+      fun();
+      fun();
+    }
+  }
+  return num * iter;
+}
+
+BENCHMARK_PARAM_MULTI(paramMulti, 1);
+BENCHMARK_RELATIVE_PARAM_MULTI(paramMultiRel, 1);
+
+BENCHMARK_PARAM_MULTI(paramMulti, 5);
+BENCHMARK_RELATIVE_PARAM_MULTI(paramMultiRel, 5);
+
+BENCHMARK_DRAW_LINE();
+
+BENCHMARK(BenchmarkSuspender_dismissing_void, iter) {
+  BenchmarkSuspender braces;
+  mt19937_64 rng;
+  while (iter--) {
+    vector<size_t> v(1 << 12, 0);
+    iota(v.begin(), v.end(), 0);
+    shuffle(v.begin(), v.end(), rng);
+    braces.dismissing([&] {
+        sort(v.begin(), v.end());
+    });
+  }
+}
+
+BENCHMARK(BenchmarkSuspender_dismissing_value, iter) {
+  BenchmarkSuspender braces;
+  mt19937_64 rng;
+  while (iter--) {
+    vector<size_t> v(1 << 12, 0);
+    iota(v.begin(), v.end(), 0);
+    shuffle(v.begin(), v.end(), rng);
+    auto s = braces.dismissing([&] {
+        sort(v.begin(), v.end());
+        return accumulate(v.begin(), v.end(), 0, [](size_t a, size_t e) {
+            return a + e;
+        });
+    });
+    doNotOptimizeAway(s);
+  }
+}
+
 int main(int argc, char** argv) {
-  google::ParseCommandLineFlags(&argc, &argv, true);
+  gflags::ParseCommandLineFlags(&argc, &argv, true);
   runBenchmarks();
   runBenchmarksOnFlag();
 }