Add Benchmark::ThreadRange() version with increment instead of multiply (#283)

* add additive thread range

* add test
diff --git a/include/benchmark/benchmark_api.h b/include/benchmark/benchmark_api.h
index 7762a42..abfbad2 100644
--- a/include/benchmark/benchmark_api.h
+++ b/include/benchmark/benchmark_api.h
@@ -595,7 +595,13 @@
   //    Foo in 4 threads
   //    Foo in 8 threads
   //    Foo in 16 threads
-  Benchmark* ThreadRange(int min_threads, int max_threads);
+  Benchmark *ThreadRange(int min_threads, int max_threads);
+
+  // For each value n in the range, run this benchmark once using n threads.
+  // min_threads and max_threads are always included in the range.
+  // stride specifies the increment. E.g. DenseThreadRange(1, 8, 3) starts
+  // a benchmark with 1, 4, 7 and 8 threads.
+  Benchmark *DenseThreadRange(int min_threads, int max_threads, int stride = 1);
 
   // Equivalent to ThreadRange(NumCPUs(), NumCPUs())
   Benchmark* ThreadPerCpu();
diff --git a/src/benchmark.cc b/src/benchmark.cc
index f0f0a43..a48f5ab 100644
--- a/src/benchmark.cc
+++ b/src/benchmark.cc
@@ -293,6 +293,7 @@
   void ComplexityLambda(BigOFunc* complexity);
   void Threads(int t);
   void ThreadRange(int min_threads, int max_threads);
+  void DenseThreadRange(int min_threads, int max_threads, int stride);
   void ThreadPerCpu();
   void SetName(const char* name);
 
@@ -548,6 +549,18 @@
   AddRange(&thread_counts_, min_threads, max_threads, 2);
 }
 
+void BenchmarkImp::DenseThreadRange(int min_threads, int max_threads,
+                                    int stride) {
+  CHECK_GT(min_threads, 0);
+  CHECK_GE(max_threads, min_threads);
+  CHECK_GE(stride, 1);
+
+  for (auto i = min_threads; i < max_threads; i += stride) {
+    thread_counts_.push_back(i);
+  }
+  thread_counts_.push_back(max_threads);
+}
+
 void BenchmarkImp::ThreadPerCpu() {
   static int num_cpus = NumCPUs();
   thread_counts_.push_back(num_cpus);
@@ -580,6 +593,7 @@
   }
 }
 
+
 Benchmark::Benchmark(const char* name)
     : imp_(new BenchmarkImp(name))
 {
@@ -687,6 +701,12 @@
   return this;
 }
 
+Benchmark *Benchmark::DenseThreadRange(int min_threads, int max_threads,
+                                       int stride) {
+  imp_->DenseThreadRange(min_threads, max_threads, stride);
+  return this;
+}
+
 Benchmark* Benchmark::ThreadPerCpu() {
   imp_->ThreadPerCpu();
   return this;
diff --git a/test/benchmark_test.cc b/test/benchmark_test.cc
index fe7d82c..eeb6e85 100644
--- a/test/benchmark_test.cc
+++ b/test/benchmark_test.cc
@@ -220,5 +220,26 @@
 
 #endif // __cplusplus >= 201103L
 
-BENCHMARK_MAIN()
+static void BM_DenseThreadRanges(benchmark::State &st) {
+  switch (st.range(0)) {
+  case 1:
+    assert(st.threads == 1 || st.threads == 2 || st.threads == 3);
+    break;
+  case 2:
+    assert(st.threads == 1 || st.threads == 3 || st.threads == 4);
+    break;
+  case 3:
+    assert(st.threads == 5 || st.threads == 8 || st.threads == 11 ||
+           st.threads == 14);
+    break;
+  default:
+    assert(false && "Invalid test case number");
+  }
+  while (st.KeepRunning()) {
+  }
+}
+BENCHMARK(BM_DenseThreadRanges)->Arg(1)->DenseThreadRange(1, 3);
+BENCHMARK(BM_DenseThreadRanges)->Arg(2)->DenseThreadRange(1, 4, 2);
+BENCHMARK(BM_DenseThreadRanges)->Arg(3)->DenseThreadRange(5, 14, 3);
 
+BENCHMARK_MAIN()