benchmark_api.h 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524
  1. // Support for registering benchmarks for functions.
  2. /* Example usage:
  3. // Define a function that executes the code to be measured a
  4. // specified number of times:
  5. static void BM_StringCreation(benchmark::State& state) {
  6. while (state.KeepRunning())
  7. std::string empty_string;
  8. }
  9. // Register the function as a benchmark
  10. BENCHMARK(BM_StringCreation);
  11. // Define another benchmark
  12. static void BM_StringCopy(benchmark::State& state) {
  13. std::string x = "hello";
  14. while (state.KeepRunning())
  15. std::string copy(x);
  16. }
  17. BENCHMARK(BM_StringCopy);
  18. // Augment the main() program to invoke benchmarks if specified
  19. // via the --benchmarks command line flag. E.g.,
  20. // my_unittest --benchmark_filter=all
  21. // my_unittest --benchmark_filter=BM_StringCreation
  22. // my_unittest --benchmark_filter=String
  23. // my_unittest --benchmark_filter='Copy|Creation'
  24. int main(int argc, char** argv) {
  25. benchmark::Initialize(&argc, argv);
  26. benchmark::RunSpecifiedBenchmarks();
  27. return 0;
  28. }
  29. // Sometimes a family of microbenchmarks can be implemented with
  30. // just one routine that takes an extra argument to specify which
  31. // one of the family of benchmarks to run. For example, the following
  32. // code defines a family of microbenchmarks for measuring the speed
  33. // of memcpy() calls of different lengths:
  34. static void BM_memcpy(benchmark::State& state) {
  35. char* src = new char[state.range_x()]; char* dst = new char[state.range_x()];
  36. memset(src, 'x', state.range_x());
  37. while (state.KeepRunning())
  38. memcpy(dst, src, state.range_x());
  39. state.SetBytesProcessed(int64_t_t(state.iterations) * int64(state.range_x()));
  40. delete[] src; delete[] dst;
  41. }
  42. BENCHMARK(BM_memcpy)->Arg(8)->Arg(64)->Arg(512)->Arg(1<<10)->Arg(8<<10);
  43. // The preceding code is quite repetitive, and can be replaced with the
  44. // following short-hand. The following invocation will pick a few
  45. // appropriate arguments in the specified range and will generate a
  46. // microbenchmark for each such argument.
  47. BENCHMARK(BM_memcpy)->Range(8, 8<<10);
  48. // You might have a microbenchmark that depends on two inputs. For
  49. // example, the following code defines a family of microbenchmarks for
  50. // measuring the speed of set insertion.
  51. static void BM_SetInsert(benchmark::State& state) {
  52. while (state.KeepRunning()) {
  53. state.PauseTiming();
  54. set<int> data = ConstructRandomSet(state.range_x());
  55. state.ResumeTiming();
  56. for (int j = 0; j < state.rangeY; ++j)
  57. data.insert(RandomNumber());
  58. }
  59. }
  60. BENCHMARK(BM_SetInsert)
  61. ->ArgPair(1<<10, 1)
  62. ->ArgPair(1<<10, 8)
  63. ->ArgPair(1<<10, 64)
  64. ->ArgPair(1<<10, 512)
  65. ->ArgPair(8<<10, 1)
  66. ->ArgPair(8<<10, 8)
  67. ->ArgPair(8<<10, 64)
  68. ->ArgPair(8<<10, 512);
  69. // The preceding code is quite repetitive, and can be replaced with
  70. // the following short-hand. The following macro will pick a few
  71. // appropriate arguments in the product of the two specified ranges
  72. // and will generate a microbenchmark for each such pair.
  73. BENCHMARK(BM_SetInsert)->RangePair(1<<10, 8<<10, 1, 512);
  74. // For more complex patterns of inputs, passing a custom function
  75. // to Apply allows programmatic specification of an
  76. // arbitrary set of arguments to run the microbenchmark on.
  77. // The following example enumerates a dense range on
  78. // one parameter, and a sparse range on the second.
  79. static benchmark::internal::Benchmark* CustomArguments(
  80. benchmark::internal::Benchmark* b) {
  81. for (int i = 0; i <= 10; ++i)
  82. for (int j = 32; j <= 1024*1024; j *= 8)
  83. b = b->ArgPair(i, j);
  84. return b;
  85. }
  86. BENCHMARK(BM_SetInsert)->Apply(CustomArguments);
  87. // Templated microbenchmarks work the same way:
  88. // Produce then consume 'size' messages 'iters' times
  89. // Measures throughput in the absence of multiprogramming.
  90. template <class Q> int BM_Sequential(benchmark::State& state) {
  91. Q q;
  92. typename Q::value_type v;
  93. while (state.KeepRunning()) {
  94. for (int i = state.range_x(); i--; )
  95. q.push(v);
  96. for (int e = state.range_x(); e--; )
  97. q.Wait(&v);
  98. }
  99. // actually messages, not bytes:
  100. state.SetBytesProcessed(
  101. static_cast<int64_t>(state.iterations())*state.range_x());
  102. }
  103. BENCHMARK_TEMPLATE(BM_Sequential, WaitQueue<int>)->Range(1<<0, 1<<10);
  104. Use `Benchmark::MinTime(double t)` to set the minimum time used to run the
  105. benchmark. This option overrides the `benchmark_min_time` flag.
  106. void BM_test(benchmark::State& state) {
  107. ... body ...
  108. }
  109. BENCHMARK(BM_test)->MinTime(2.0); // Run for at least 2 seconds.
  110. In a multithreaded test, it is guaranteed that none of the threads will start
  111. until all have called KeepRunning, and all will have finished before KeepRunning
  112. returns false. As such, any global setup or teardown you want to do can be
  113. wrapped in a check against the thread index:
  114. static void BM_MultiThreaded(benchmark::State& state) {
  115. if (state.thread_index == 0) {
  116. // Setup code here.
  117. }
  118. while (state.KeepRunning()) {
  119. // Run the test as normal.
  120. }
  121. if (state.thread_index == 0) {
  122. // Teardown code here.
  123. }
  124. }
  125. BENCHMARK(BM_MultiThreaded)->Threads(4);
  126. */
  127. #ifndef BENCHMARK_BENCHMARK_API_H_
  128. #define BENCHMARK_BENCHMARK_API_H_
  129. #include <assert.h>
  130. #include <stddef.h>
  131. #include <stdint.h>
  132. #include "macros.h"
  133. namespace benchmark {
  134. class BenchmarkReporter;
  135. void Initialize(int* argc, const char** argv);
  136. // Otherwise, run all benchmarks specified by the --benchmark_filter flag,
  137. // and exit after running the benchmarks.
  138. void RunSpecifiedBenchmarks();
  139. void RunSpecifiedBenchmarks(BenchmarkReporter* reporter);
  140. // If this routine is called, peak memory allocation past this point in the
  141. // benchmark is reported at the end of the benchmark report line. (It is
  142. // computed by running the benchmark once with a single iteration and a memory
  143. // tracer.)
  144. // TODO(dominic)
  145. // void MemoryUsage();
  146. namespace internal {
  147. class Benchmark;
  148. class BenchmarkImp;
  149. template <class T> struct Voider {
  150. typedef void type;
  151. };
  152. template <class T, class = void>
  153. struct EnableIfString {};
  154. template <class T>
  155. struct EnableIfString<T, typename Voider<typename T::basic_string>::type> {
  156. typedef int type;
  157. };
  158. void UseCharPointer(char const volatile*);
  159. } // end namespace internal
  160. // The DoNotOptimize(...) function can be used to prevent a value or
  161. // expression from being optimized away by the compiler. This function is
  162. // intented to add little to no overhead.
  163. // See: http://stackoverflow.com/questions/28287064
  164. #if defined(__clang__) && defined(__GNUC__)
  165. // TODO(ericwf): Clang has a bug where it tries to always use a register
  166. // even if value must be stored in memory. This causes codegen to fail.
  167. // To work around this we remove the "r" modifier so the operand is always
  168. // loaded into memory.
  169. template <class Tp>
  170. inline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp const& value) {
  171. asm volatile("" : "+m" (const_cast<Tp&>(value)));
  172. }
  173. #elif defined(__GNUC__)
  174. template <class Tp>
  175. inline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp const& value) {
  176. asm volatile("" : "+rm" (const_cast<Tp&>(value)));
  177. }
  178. #else
  179. template <class Tp>
  180. inline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp const& value) {
  181. internal::UseCharPointer(&reinterpret_cast<char const volatile&>(value));
  182. }
  183. #endif
  184. // State is passed to a running Benchmark and contains state for the
  185. // benchmark to use.
  186. class State {
  187. public:
  188. State(size_t max_iters, bool has_x, int x, bool has_y, int y, int thread_i);
  189. // Returns true iff the benchmark should continue through another iteration.
  190. // NOTE: A benchmark may not return from the test until KeepRunning() has
  191. // returned false.
  192. bool KeepRunning() {
  193. if (BENCHMARK_BUILTIN_EXPECT(!started_, false)) {
  194. ResumeTiming();
  195. started_ = true;
  196. }
  197. bool const res = total_iterations_++ < max_iterations;
  198. if (BENCHMARK_BUILTIN_EXPECT(!res, false)) {
  199. assert(started_);
  200. PauseTiming();
  201. // Total iterations now is one greater than max iterations. Fix this.
  202. total_iterations_ = max_iterations;
  203. }
  204. return res;
  205. }
  206. // REQUIRES: timer is running
  207. // Stop the benchmark timer. If not called, the timer will be
  208. // automatically stopped after KeepRunning() returns false for the first time.
  209. //
  210. // For threaded benchmarks the PauseTiming() function acts
  211. // like a barrier. I.e., the ith call by a particular thread to this
  212. // function will block until all threads have made their ith call.
  213. // The timer will stop when the last thread has called this function.
  214. //
  215. // NOTE: PauseTiming()/ResumeTiming() are relatively
  216. // heavyweight, and so their use should generally be avoided
  217. // within each benchmark iteration, if possible.
  218. void PauseTiming();
  219. // REQUIRES: timer is not running
  220. // Start the benchmark timer. The timer is NOT running on entrance to the
  221. // benchmark function. It begins running after the first call to KeepRunning()
  222. //
  223. // For threaded benchmarks the ResumeTiming() function acts
  224. // like a barrier. I.e., the ith call by a particular thread to this
  225. // function will block until all threads have made their ith call.
  226. // The timer will start when the last thread has called this function.
  227. //
  228. // NOTE: PauseTiming()/ResumeTiming() are relatively
  229. // heavyweight, and so their use should generally be avoided
  230. // within each benchmark iteration, if possible.
  231. void ResumeTiming();
  232. // Set the number of bytes processed by the current benchmark
  233. // execution. This routine is typically called once at the end of a
  234. // throughput oriented benchmark. If this routine is called with a
  235. // value > 0, the report is printed in MB/sec instead of nanoseconds
  236. // per iteration.
  237. //
  238. // REQUIRES: a benchmark has exited its KeepRunning loop.
  239. BENCHMARK_ALWAYS_INLINE
  240. void SetBytesProcessed(size_t bytes) {
  241. bytes_processed_ = bytes;
  242. }
  243. BENCHMARK_ALWAYS_INLINE
  244. size_t bytes_processed() const {
  245. return bytes_processed_;
  246. }
  247. // If this routine is called with items > 0, then an items/s
  248. // label is printed on the benchmark report line for the currently
  249. // executing benchmark. It is typically called at the end of a processing
  250. // benchmark where a processing items/second output is desired.
  251. //
  252. // REQUIRES: a benchmark has exited its KeepRunning loop.
  253. BENCHMARK_ALWAYS_INLINE
  254. void SetItemsProcessed(size_t items) {
  255. items_processed_ = items;
  256. }
  257. BENCHMARK_ALWAYS_INLINE
  258. size_t items_processed() const {
  259. return items_processed_;
  260. }
  261. // If this routine is called, the specified label is printed at the
  262. // end of the benchmark report line for the currently executing
  263. // benchmark. Example:
  264. // static void BM_Compress(int iters) {
  265. // ...
  266. // double compress = input_size / output_size;
  267. // benchmark::SetLabel(StringPrintf("compress:%.1f%%", 100.0*compression));
  268. // }
  269. // Produces output that looks like:
  270. // BM_Compress 50 50 14115038 compress:27.3%
  271. //
  272. // REQUIRES: a benchmark has exited its KeepRunning loop.
  273. void SetLabel(const char* label);
  274. // Allow the use of std::string without actually including <string>.
  275. // This function does not participate in overload resolution unless StringType
  276. // has the nested typename `basic_string`. This typename should be provided
  277. // as an injected class name in the case of std::string.
  278. template <class StringType>
  279. void SetLabel(StringType const & str,
  280. typename internal::EnableIfString<StringType>::type = 1) {
  281. this->SetLabel(str.c_str());
  282. }
  283. // Range arguments for this run. CHECKs if the argument has been set.
  284. BENCHMARK_ALWAYS_INLINE
  285. int range_x() const {
  286. assert(has_range_x_);
  287. ((void)has_range_x_); // Prevent unused warning.
  288. return range_x_;
  289. }
  290. BENCHMARK_ALWAYS_INLINE
  291. int range_y() const {
  292. assert(has_range_y_);
  293. ((void)has_range_y_); // Prevent unused warning.
  294. return range_y_;
  295. }
  296. BENCHMARK_ALWAYS_INLINE
  297. size_t iterations() const { return total_iterations_; }
  298. private:
  299. bool started_;
  300. size_t total_iterations_;
  301. bool has_range_x_;
  302. int range_x_;
  303. bool has_range_y_;
  304. int range_y_;
  305. size_t bytes_processed_;
  306. size_t items_processed_;
  307. public:
  308. const int thread_index;
  309. const size_t max_iterations;
  310. private:
  311. BENCHMARK_DISALLOW_COPY_AND_ASSIGN(State);
  312. };
  313. namespace internal {
  314. typedef void(Function)(State&);
  315. // ------------------------------------------------------
  316. // Benchmark registration object. The BENCHMARK() macro expands
  317. // into an internal::Benchmark* object. Various methods can
  318. // be called on this object to change the properties of the benchmark.
  319. // Each method returns "this" so that multiple method calls can
  320. // chained into one expression.
  321. class Benchmark {
  322. public:
  323. Benchmark(const char* name, Function* f);
  324. ~Benchmark();
  325. // Note: the following methods all return "this" so that multiple
  326. // method calls can be chained together in one expression.
  327. // Run this benchmark once with "x" as the extra argument passed
  328. // to the function.
  329. // REQUIRES: The function passed to the constructor must accept an arg1.
  330. Benchmark* Arg(int x);
  331. // Run this benchmark once for a number of values picked from the
  332. // range [start..limit]. (start and limit are always picked.)
  333. // REQUIRES: The function passed to the constructor must accept an arg1.
  334. Benchmark* Range(int start, int limit);
  335. // Run this benchmark once for every value in the range [start..limit]
  336. // REQUIRES: The function passed to the constructor must accept an arg1.
  337. Benchmark* DenseRange(int start, int limit);
  338. // Run this benchmark once with "x,y" as the extra arguments passed
  339. // to the function.
  340. // REQUIRES: The function passed to the constructor must accept arg1,arg2.
  341. Benchmark* ArgPair(int x, int y);
  342. // Pick a set of values A from the range [lo1..hi1] and a set
  343. // of values B from the range [lo2..hi2]. Run the benchmark for
  344. // every pair of values in the cartesian product of A and B
  345. // (i.e., for all combinations of the values in A and B).
  346. // REQUIRES: The function passed to the constructor must accept arg1,arg2.
  347. Benchmark* RangePair(int lo1, int hi1, int lo2, int hi2);
  348. // Pass this benchmark object to *func, which can customize
  349. // the benchmark by calling various methods like Arg, ArgPair,
  350. // Threads, etc.
  351. Benchmark* Apply(void (*func)(Benchmark* benchmark));
  352. // Set the minimum amount of time to use when running this benchmark. This
  353. // option overrides the `benchmark_min_time` flag.
  354. Benchmark* MinTime(double t);
  355. // If a particular benchmark is I/O bound, or if for some reason CPU
  356. // timings are not representative, call this method. If called, the elapsed
  357. // time will be used to control how many iterations are run, and in the
  358. // printing of items/second or MB/seconds values. If not called, the cpu
  359. // time used by the benchmark will be used.
  360. Benchmark* UseRealTime();
  361. // Support for running multiple copies of the same benchmark concurrently
  362. // in multiple threads. This may be useful when measuring the scaling
  363. // of some piece of code.
  364. // Run one instance of this benchmark concurrently in t threads.
  365. Benchmark* Threads(int t);
  366. // Pick a set of values T from [min_threads,max_threads].
  367. // min_threads and max_threads are always included in T. Run this
  368. // benchmark once for each value in T. The benchmark run for a
  369. // particular value t consists of t threads running the benchmark
  370. // function concurrently. For example, consider:
  371. // BENCHMARK(Foo)->ThreadRange(1,16);
  372. // This will run the following benchmarks:
  373. // Foo in 1 thread
  374. // Foo in 2 threads
  375. // Foo in 4 threads
  376. // Foo in 8 threads
  377. // Foo in 16 threads
  378. Benchmark* ThreadRange(int min_threads, int max_threads);
  379. // Equivalent to ThreadRange(NumCPUs(), NumCPUs())
  380. Benchmark* ThreadPerCpu();
  381. // Used inside the benchmark implementation
  382. struct Instance;
  383. private:
  384. BenchmarkImp* imp_;
  385. BENCHMARK_DISALLOW_COPY_AND_ASSIGN(Benchmark);
  386. };
  387. } // end namespace internal
  388. } // end namespace benchmark
  389. // ------------------------------------------------------
  390. // Macro to register benchmarks
  391. // Check that __COUNTER__ is defined and that __COUNTER__ increases by 1
  392. // every time it is expanded. X + 1 == X + 0 is used in case X is defined to be
  393. // empty. If X is empty the expression becomes (+1 == +0).
  394. #if defined(__COUNTER__) && (__COUNTER__ + 1 == __COUNTER__ + 0)
  395. #define BENCHMARK_PRIVATE_UNIQUE_ID __COUNTER__
  396. #else
  397. #define BENCHMARK_PRIVATE_UNIQUE_ID __LINE__
  398. #endif
  399. // Helpers for generating unique variable names
  400. #define BENCHMARK_PRIVATE_NAME(n) \
  401. BENCHMARK_PRIVATE_CONCAT(_benchmark_, BENCHMARK_PRIVATE_UNIQUE_ID, n)
  402. #define BENCHMARK_PRIVATE_CONCAT(a, b, c) BENCHMARK_PRIVATE_CONCAT2(a, b, c)
  403. #define BENCHMARK_PRIVATE_CONCAT2(a, b, c) a##b##c
  404. #define BENCHMARK_PRIVATE_DECLARE(n) \
  405. static ::benchmark::internal::Benchmark* \
  406. BENCHMARK_PRIVATE_NAME(n) BENCHMARK_UNUSED
  407. #define BENCHMARK(n) \
  408. BENCHMARK_PRIVATE_DECLARE(n) = (new ::benchmark::internal::Benchmark(#n, n))
  409. // Old-style macros
  410. #define BENCHMARK_WITH_ARG(n, a) BENCHMARK(n)->Arg((a))
  411. #define BENCHMARK_WITH_ARG2(n, a1, a2) BENCHMARK(n)->ArgPair((a1), (a2))
  412. #define BENCHMARK_RANGE(n, lo, hi) BENCHMARK(n)->Range((lo), (hi))
  413. #define BENCHMARK_RANGE2(n, l1, h1, l2, h2) \
  414. BENCHMARK(n)->RangePair((l1), (h1), (l2), (h2))
  415. // This will register a benchmark for a templatized function. For example:
  416. //
  417. // template<int arg>
  418. // void BM_Foo(int iters);
  419. //
  420. // BENCHMARK_TEMPLATE(BM_Foo, 1);
  421. //
  422. // will register BM_Foo<1> as a benchmark.
  423. #define BENCHMARK_TEMPLATE1(n, a) \
  424. BENCHMARK_PRIVATE_DECLARE(n) = \
  425. (new ::benchmark::internal::Benchmark(#n "<" #a ">", n<a>))
  426. #define BENCHMARK_TEMPLATE2(n, a, b) \
  427. BENCHMARK_PRIVATE_DECLARE(n) = \
  428. (new ::benchmark::internal::Benchmark(#n "<" #a "," #b ">", n<a, b>))
  429. #if __cplusplus >= 201103L
  430. #define BENCHMARK_TEMPLATE(n, ...) \
  431. BENCHMARK_PRIVATE_DECLARE(n) = \
  432. (new ::benchmark::internal::Benchmark( \
  433. #n "<" #__VA_ARGS__ ">", n<__VA_ARGS__>))
  434. #else
  435. #define BENCHMARK_TEMPLATE(n, a) BENCHMARK_TEMPLATE1(n, a)
  436. #endif
  437. // Helper macro to create a main routine in a test that runs the benchmarks
  438. #define BENCHMARK_MAIN() \
  439. int main(int argc, const char** argv) { \
  440. ::benchmark::Initialize(&argc, argv); \
  441. ::benchmark::RunSpecifiedBenchmarks(); \
  442. }
  443. #endif // BENCHMARK_BENCHMARK_API_H_