add bm_max/min_iters and bm_regex
authorSpencer Ahrens <sahrens@fb.com>
Sat, 30 Jun 2012 18:01:06 +0000 (11:01 -0700)
committerTudor Bosman <tudorb@fb.com>
Fri, 13 Jul 2012 23:27:38 +0000 (16:27 -0700)
Summary: These were handy in the old framework and easy enough to add.

Test Plan:
ran ThreadCachedIntTest - got better (but not perfect due to
subtraction of single-threaded baseline from multi-threaded results).

Reviewed By: sherman.ye@fb.com

FB internal diff: D490324

folly/Benchmark.cpp
folly/Benchmark.h
folly/test/ThreadCachedIntTest.cpp

index aa83804b98e63960950230c1636764bfc6171f7e..3b6a737f5c039ac88aba6a64d3262be43a614a65 100644 (file)
@@ -20,7 +20,9 @@
 #include "Foreach.h"
 #include "json.h"
 #include "String.h"
+
 #include <algorithm>
+#include <boost/regex.hpp>
 #include <cmath>
 #include <iostream>
 #include <limits>
@@ -32,6 +34,16 @@ using namespace std;
 DEFINE_bool(benchmark, false, "Run benchmarks.");
 DEFINE_bool(json, false, "Output in JSON format.");
 
+DEFINE_string(bm_regex, "",
+              "Only benchmarks whose names match this regex will be run.");
+
+DEFINE_int64(bm_min_usec, 100,
+             "Minimum # of microseconds we'll accept for each benchmark.");
+
+DEFINE_int32(bm_max_secs, 1,
+             "Maximum # of seconds we'll spend on each benchmark.");
+
+
 namespace folly {
 
 BenchmarkSuspender::NanosecondsSpent BenchmarkSuspender::nsSpent;
@@ -191,17 +203,18 @@ static double runBenchmarkGetNSPerIteration(const BenchmarkFun& fun,
     CHECK_EQ(1, ts.tv_nsec) << "Clock too coarse, upgrade your kernel.";
     resolutionInNs = ts.tv_nsec;
   }
-  // Whe choose a minimum minimum (sic) of 10,000 nanoseconds, but if
+  // We choose a minimum minimum (sic) of 100,000 nanoseconds, but if
   // the clock resolution is worse than that, it will be larger. In
   // essence we're aiming at making the quantization noise 0.01%.
-  static const auto minNanoseconds = min(resolutionInNs * 100000, 1000000000UL);
+  static const auto minNanoseconds =
+    max(FLAGS_bm_min_usec * 1000UL, min(resolutionInNs * 100000, 1000000000UL));
 
   // We do measurements in several epochs and take the minimum, to
   // account for jitter.
   static const unsigned int epochs = 1000;
   // We establish a total time budget as we don't want a measurement
   // to take too long. This will curtail the number of actual epochs.
-  static const uint64_t timeBudgetInNs = 1000000000;
+  const uint64_t timeBudgetInNs = FLAGS_bm_max_secs * 1000000000;
   timespec global;
   CHECK_EQ(0, clock_gettime(CLOCK_REALTIME, &global));
 
@@ -209,7 +222,7 @@ static double runBenchmarkGetNSPerIteration(const BenchmarkFun& fun,
   size_t actualEpochs = 0;
 
   for (; actualEpochs < epochs; ++actualEpochs) {
-    for (unsigned int n = 1; n < (1U << 30); n *= 2) {
+    for (unsigned int n = 1; n < (1UL << 30); n *= 2) {
       auto const nsecs = fun(n);
       if (nsecs < minNanoseconds) {
         continue;
@@ -394,15 +407,24 @@ void runBenchmarks() {
   vector<tuple<const char*, const char*, double>> results;
   results.reserve(benchmarks.size() - 1);
 
+  std::unique_ptr<boost::regex> bmRegex;
+  if (!FLAGS_bm_regex.empty()) {
+    bmRegex.reset(new boost::regex(FLAGS_bm_regex));
+  }
+
   // PLEASE KEEP QUIET. MEASUREMENTS IN PROGRESS.
 
   auto const globalBaseline = runBenchmarkGetNSPerIteration(
     get<2>(benchmarks.front()), 0);
   FOR_EACH_RANGE (i, 1, benchmarks.size()) {
-    auto elapsed = strcmp(get<1>(benchmarks[i]), "-") == 0
-      ? 0.0 // skip the separators
-      : runBenchmarkGetNSPerIteration(get<2>(benchmarks[i]),
-                                      globalBaseline);
+    double elapsed = 0.0;
+    if (!strcmp(get<1>(benchmarks[i]), "-") == 0) { // skip separators
+      if (bmRegex && !boost::regex_search(get<1>(benchmarks[i]), *bmRegex)) {
+        continue;
+      }
+      elapsed = runBenchmarkGetNSPerIteration(get<2>(benchmarks[i]),
+                                              globalBaseline);
+    }
     results.emplace_back(get<0>(benchmarks[i]),
                          get<1>(benchmarks[i]), elapsed);
   }
index 415fd7abec3a3e42c36875ab2fb7550b41529756..d5bd4cca9e67b8d1b65c390fbb4cfeafd797976c 100644 (file)
@@ -28,6 +28,7 @@
 
 DECLARE_bool(benchmark);
 
+
 namespace folly {
 
 /**
index c6766f8972ba48a2e4161d81c5300d50c9586305..cfe19e18c5fa8e72f8a8db4eb03dafa8a3d1cbbb 100644 (file)
@@ -238,7 +238,7 @@ int main(int argc, char** argv) {
   testing::InitGoogleTest(&argc, argv);
   google::ParseCommandLineFlags(&argc, &argv, true);
   google::SetCommandLineOptionWithMode(
-    "bm_max_iters", "10000000", google::SET_FLAG_IF_DEFAULT
+    "bm_min_usec", "10000", google::SET_FLAG_IF_DEFAULT
   );
   if (FLAGS_benchmark) {
     folly::runBenchmarks();