user_counters_test.cc 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555
  1. #undef NDEBUG
  2. #include "benchmark/benchmark.h"
  3. #include "output_test.h"
  4. // ========================================================================= //
  5. // ---------------------- Testing Prologue Output -------------------------- //
  6. // ========================================================================= //
  7. // clang-format off
  8. ADD_CASES(TC_ConsoleOut,
  9. {{"^[-]+$", MR_Next},
  10. {"^Benchmark %s Time %s CPU %s Iterations UserCounters...$", MR_Next},
  11. {"^[-]+$", MR_Next}});
  12. ADD_CASES(TC_CSVOut, {{"%csv_header,\"bar\",\"foo\""}});
  13. // clang-format on
  14. // ========================================================================= //
  15. // ------------------------- Simple Counters Output ------------------------ //
  16. // ========================================================================= //
  17. void BM_Counters_Simple(benchmark::State& state) {
  18. for (auto _ : state) {
  19. }
  20. state.counters["foo"] = 1;
  21. state.counters["bar"] = 2 * (double)state.iterations();
  22. }
  23. BENCHMARK(BM_Counters_Simple);
  24. ADD_CASES(TC_ConsoleOut,
  25. {{"^BM_Counters_Simple %console_report bar=%hrfloat foo=%hrfloat$"}});
  26. ADD_CASES(TC_JSONOut, {{"\"name\": \"BM_Counters_Simple\",$"},
  27. {"\"family_index\": 0,$", MR_Next},
  28. {"\"per_family_instance_index\": 0,$", MR_Next},
  29. {"\"run_name\": \"BM_Counters_Simple\",$", MR_Next},
  30. {"\"run_type\": \"iteration\",$", MR_Next},
  31. {"\"repetitions\": 1,$", MR_Next},
  32. {"\"repetition_index\": 0,$", MR_Next},
  33. {"\"threads\": 1,$", MR_Next},
  34. {"\"iterations\": %int,$", MR_Next},
  35. {"\"real_time\": %float,$", MR_Next},
  36. {"\"cpu_time\": %float,$", MR_Next},
  37. {"\"time_unit\": \"ns\",$", MR_Next},
  38. {"\"bar\": %float,$", MR_Next},
  39. {"\"foo\": %float$", MR_Next},
  40. {"}", MR_Next}});
  41. ADD_CASES(TC_CSVOut, {{"^\"BM_Counters_Simple\",%csv_report,%float,%float$"}});
  42. // VS2013 does not allow this function to be passed as a lambda argument
  43. // to CHECK_BENCHMARK_RESULTS()
  44. void CheckSimple(Results const& e) {
  45. double its = e.NumIterations();
  46. CHECK_COUNTER_VALUE(e, int, "foo", EQ, 1);
  47. // check that the value of bar is within 0.1% of the expected value
  48. CHECK_FLOAT_COUNTER_VALUE(e, "bar", EQ, 2. * its, 0.001);
  49. }
  50. CHECK_BENCHMARK_RESULTS("BM_Counters_Simple", &CheckSimple);
  51. // ========================================================================= //
  52. // --------------------- Counters+Items+Bytes/s Output --------------------- //
  53. // ========================================================================= //
  54. namespace {
  55. int num_calls1 = 0;
  56. }
  57. void BM_Counters_WithBytesAndItemsPSec(benchmark::State& state) {
  58. for (auto _ : state) {
  59. // This test requires a non-zero CPU time to avoid divide-by-zero
  60. benchmark::DoNotOptimize(state.iterations());
  61. }
  62. state.counters["foo"] = 1;
  63. state.counters["bar"] = ++num_calls1;
  64. state.SetBytesProcessed(364);
  65. state.SetItemsProcessed(150);
  66. }
  67. BENCHMARK(BM_Counters_WithBytesAndItemsPSec);
  68. ADD_CASES(TC_ConsoleOut, {{"^BM_Counters_WithBytesAndItemsPSec %console_report "
  69. "bar=%hrfloat bytes_per_second=%hrfloat/s "
  70. "foo=%hrfloat items_per_second=%hrfloat/s$"}});
  71. ADD_CASES(TC_JSONOut,
  72. {{"\"name\": \"BM_Counters_WithBytesAndItemsPSec\",$"},
  73. {"\"family_index\": 1,$", MR_Next},
  74. {"\"per_family_instance_index\": 0,$", MR_Next},
  75. {"\"run_name\": \"BM_Counters_WithBytesAndItemsPSec\",$", MR_Next},
  76. {"\"run_type\": \"iteration\",$", MR_Next},
  77. {"\"repetitions\": 1,$", MR_Next},
  78. {"\"repetition_index\": 0,$", MR_Next},
  79. {"\"threads\": 1,$", MR_Next},
  80. {"\"iterations\": %int,$", MR_Next},
  81. {"\"real_time\": %float,$", MR_Next},
  82. {"\"cpu_time\": %float,$", MR_Next},
  83. {"\"time_unit\": \"ns\",$", MR_Next},
  84. {"\"bar\": %float,$", MR_Next},
  85. {"\"bytes_per_second\": %float,$", MR_Next},
  86. {"\"foo\": %float,$", MR_Next},
  87. {"\"items_per_second\": %float$", MR_Next},
  88. {"}", MR_Next}});
  89. ADD_CASES(TC_CSVOut, {{"^\"BM_Counters_WithBytesAndItemsPSec\","
  90. "%csv_bytes_items_report,%float,%float$"}});
  91. // VS2013 does not allow this function to be passed as a lambda argument
  92. // to CHECK_BENCHMARK_RESULTS()
  93. void CheckBytesAndItemsPSec(Results const& e) {
  94. double t = e.DurationCPUTime(); // this (and not real time) is the time used
  95. CHECK_COUNTER_VALUE(e, int, "foo", EQ, 1);
  96. CHECK_COUNTER_VALUE(e, int, "bar", EQ, num_calls1);
  97. // check that the values are within 0.1% of the expected values
  98. CHECK_FLOAT_RESULT_VALUE(e, "bytes_per_second", EQ, 364. / t, 0.001);
  99. CHECK_FLOAT_RESULT_VALUE(e, "items_per_second", EQ, 150. / t, 0.001);
  100. }
  101. CHECK_BENCHMARK_RESULTS("BM_Counters_WithBytesAndItemsPSec",
  102. &CheckBytesAndItemsPSec);
  103. // ========================================================================= //
  104. // ------------------------- Rate Counters Output -------------------------- //
  105. // ========================================================================= //
  106. void BM_Counters_Rate(benchmark::State& state) {
  107. for (auto _ : state) {
  108. // This test requires a non-zero CPU time to avoid divide-by-zero
  109. benchmark::DoNotOptimize(state.iterations());
  110. }
  111. namespace bm = benchmark;
  112. state.counters["foo"] = bm::Counter{1, bm::Counter::kIsRate};
  113. state.counters["bar"] = bm::Counter{2, bm::Counter::kIsRate};
  114. }
  115. BENCHMARK(BM_Counters_Rate);
  116. ADD_CASES(
  117. TC_ConsoleOut,
  118. {{"^BM_Counters_Rate %console_report bar=%hrfloat/s foo=%hrfloat/s$"}});
  119. ADD_CASES(TC_JSONOut, {{"\"name\": \"BM_Counters_Rate\",$"},
  120. {"\"family_index\": 2,$", MR_Next},
  121. {"\"per_family_instance_index\": 0,$", MR_Next},
  122. {"\"run_name\": \"BM_Counters_Rate\",$", MR_Next},
  123. {"\"run_type\": \"iteration\",$", MR_Next},
  124. {"\"repetitions\": 1,$", MR_Next},
  125. {"\"repetition_index\": 0,$", MR_Next},
  126. {"\"threads\": 1,$", MR_Next},
  127. {"\"iterations\": %int,$", MR_Next},
  128. {"\"real_time\": %float,$", MR_Next},
  129. {"\"cpu_time\": %float,$", MR_Next},
  130. {"\"time_unit\": \"ns\",$", MR_Next},
  131. {"\"bar\": %float,$", MR_Next},
  132. {"\"foo\": %float$", MR_Next},
  133. {"}", MR_Next}});
  134. ADD_CASES(TC_CSVOut, {{"^\"BM_Counters_Rate\",%csv_report,%float,%float$"}});
  135. // VS2013 does not allow this function to be passed as a lambda argument
  136. // to CHECK_BENCHMARK_RESULTS()
  137. void CheckRate(Results const& e) {
  138. double t = e.DurationCPUTime(); // this (and not real time) is the time used
  139. // check that the values are within 0.1% of the expected values
  140. CHECK_FLOAT_COUNTER_VALUE(e, "foo", EQ, 1. / t, 0.001);
  141. CHECK_FLOAT_COUNTER_VALUE(e, "bar", EQ, 2. / t, 0.001);
  142. }
  143. CHECK_BENCHMARK_RESULTS("BM_Counters_Rate", &CheckRate);
  144. // ========================================================================= //
  145. // ----------------------- Inverted Counters Output ------------------------ //
  146. // ========================================================================= //
  147. void BM_Invert(benchmark::State& state) {
  148. for (auto _ : state) {
  149. // This test requires a non-zero CPU time to avoid divide-by-zero
  150. benchmark::DoNotOptimize(state.iterations());
  151. }
  152. namespace bm = benchmark;
  153. state.counters["foo"] = bm::Counter{0.0001, bm::Counter::kInvert};
  154. state.counters["bar"] = bm::Counter{10000, bm::Counter::kInvert};
  155. }
  156. BENCHMARK(BM_Invert);
  157. ADD_CASES(TC_ConsoleOut,
  158. {{"^BM_Invert %console_report bar=%hrfloatu foo=%hrfloatk$"}});
  159. ADD_CASES(TC_JSONOut, {{"\"name\": \"BM_Invert\",$"},
  160. {"\"family_index\": 3,$", MR_Next},
  161. {"\"per_family_instance_index\": 0,$", MR_Next},
  162. {"\"run_name\": \"BM_Invert\",$", MR_Next},
  163. {"\"run_type\": \"iteration\",$", MR_Next},
  164. {"\"repetitions\": 1,$", MR_Next},
  165. {"\"repetition_index\": 0,$", MR_Next},
  166. {"\"threads\": 1,$", MR_Next},
  167. {"\"iterations\": %int,$", MR_Next},
  168. {"\"real_time\": %float,$", MR_Next},
  169. {"\"cpu_time\": %float,$", MR_Next},
  170. {"\"time_unit\": \"ns\",$", MR_Next},
  171. {"\"bar\": %float,$", MR_Next},
  172. {"\"foo\": %float$", MR_Next},
  173. {"}", MR_Next}});
  174. ADD_CASES(TC_CSVOut, {{"^\"BM_Invert\",%csv_report,%float,%float$"}});
  175. // VS2013 does not allow this function to be passed as a lambda argument
  176. // to CHECK_BENCHMARK_RESULTS()
  177. void CheckInvert(Results const& e) {
  178. CHECK_FLOAT_COUNTER_VALUE(e, "foo", EQ, 10000, 0.0001);
  179. CHECK_FLOAT_COUNTER_VALUE(e, "bar", EQ, 0.0001, 0.0001);
  180. }
  181. CHECK_BENCHMARK_RESULTS("BM_Invert", &CheckInvert);
  182. // ========================================================================= //
  183. // ------------------------- InvertedRate Counters Output
  184. // -------------------------- //
  185. // ========================================================================= //
  186. void BM_Counters_InvertedRate(benchmark::State& state) {
  187. for (auto _ : state) {
  188. // This test requires a non-zero CPU time to avoid divide-by-zero
  189. benchmark::DoNotOptimize(state.iterations());
  190. }
  191. namespace bm = benchmark;
  192. state.counters["foo"] =
  193. bm::Counter{1, bm::Counter::kIsRate | bm::Counter::kInvert};
  194. state.counters["bar"] =
  195. bm::Counter{8192, bm::Counter::kIsRate | bm::Counter::kInvert};
  196. }
  197. BENCHMARK(BM_Counters_InvertedRate);
  198. ADD_CASES(TC_ConsoleOut, {{"^BM_Counters_InvertedRate %console_report "
  199. "bar=%hrfloats foo=%hrfloats$"}});
  200. ADD_CASES(TC_JSONOut,
  201. {{"\"name\": \"BM_Counters_InvertedRate\",$"},
  202. {"\"family_index\": 4,$", MR_Next},
  203. {"\"per_family_instance_index\": 0,$", MR_Next},
  204. {"\"run_name\": \"BM_Counters_InvertedRate\",$", MR_Next},
  205. {"\"run_type\": \"iteration\",$", MR_Next},
  206. {"\"repetitions\": 1,$", MR_Next},
  207. {"\"repetition_index\": 0,$", MR_Next},
  208. {"\"threads\": 1,$", MR_Next},
  209. {"\"iterations\": %int,$", MR_Next},
  210. {"\"real_time\": %float,$", MR_Next},
  211. {"\"cpu_time\": %float,$", MR_Next},
  212. {"\"time_unit\": \"ns\",$", MR_Next},
  213. {"\"bar\": %float,$", MR_Next},
  214. {"\"foo\": %float$", MR_Next},
  215. {"}", MR_Next}});
  216. ADD_CASES(TC_CSVOut,
  217. {{"^\"BM_Counters_InvertedRate\",%csv_report,%float,%float$"}});
  218. // VS2013 does not allow this function to be passed as a lambda argument
  219. // to CHECK_BENCHMARK_RESULTS()
  220. void CheckInvertedRate(Results const& e) {
  221. double t = e.DurationCPUTime(); // this (and not real time) is the time used
  222. // check that the values are within 0.1% of the expected values
  223. CHECK_FLOAT_COUNTER_VALUE(e, "foo", EQ, t, 0.001);
  224. CHECK_FLOAT_COUNTER_VALUE(e, "bar", EQ, t / 8192.0, 0.001);
  225. }
  226. CHECK_BENCHMARK_RESULTS("BM_Counters_InvertedRate", &CheckInvertedRate);
  227. // ========================================================================= //
  228. // ------------------------- Thread Counters Output ------------------------ //
  229. // ========================================================================= //
  230. void BM_Counters_Threads(benchmark::State& state) {
  231. for (auto _ : state) {
  232. }
  233. state.counters["foo"] = 1;
  234. state.counters["bar"] = 2;
  235. }
  236. BENCHMARK(BM_Counters_Threads)->ThreadRange(1, 8);
  237. ADD_CASES(TC_ConsoleOut, {{"^BM_Counters_Threads/threads:%int %console_report "
  238. "bar=%hrfloat foo=%hrfloat$"}});
  239. ADD_CASES(TC_JSONOut,
  240. {{"\"name\": \"BM_Counters_Threads/threads:%int\",$"},
  241. {"\"family_index\": 5,$", MR_Next},
  242. {"\"per_family_instance_index\": 0,$", MR_Next},
  243. {"\"run_name\": \"BM_Counters_Threads/threads:%int\",$", MR_Next},
  244. {"\"run_type\": \"iteration\",$", MR_Next},
  245. {"\"repetitions\": 1,$", MR_Next},
  246. {"\"repetition_index\": 0,$", MR_Next},
  247. {"\"threads\": 1,$", MR_Next},
  248. {"\"iterations\": %int,$", MR_Next},
  249. {"\"real_time\": %float,$", MR_Next},
  250. {"\"cpu_time\": %float,$", MR_Next},
  251. {"\"time_unit\": \"ns\",$", MR_Next},
  252. {"\"bar\": %float,$", MR_Next},
  253. {"\"foo\": %float$", MR_Next},
  254. {"}", MR_Next}});
  255. ADD_CASES(
  256. TC_CSVOut,
  257. {{"^\"BM_Counters_Threads/threads:%int\",%csv_report,%float,%float$"}});
  258. // VS2013 does not allow this function to be passed as a lambda argument
  259. // to CHECK_BENCHMARK_RESULTS()
  260. void CheckThreads(Results const& e) {
  261. CHECK_COUNTER_VALUE(e, int, "foo", EQ, e.NumThreads());
  262. CHECK_COUNTER_VALUE(e, int, "bar", EQ, 2 * e.NumThreads());
  263. }
  264. CHECK_BENCHMARK_RESULTS("BM_Counters_Threads/threads:%int", &CheckThreads);
  265. // ========================================================================= //
  266. // ---------------------- ThreadAvg Counters Output ------------------------ //
  267. // ========================================================================= //
  268. void BM_Counters_AvgThreads(benchmark::State& state) {
  269. for (auto _ : state) {
  270. }
  271. namespace bm = benchmark;
  272. state.counters["foo"] = bm::Counter{1, bm::Counter::kAvgThreads};
  273. state.counters["bar"] = bm::Counter{2, bm::Counter::kAvgThreads};
  274. }
  275. BENCHMARK(BM_Counters_AvgThreads)->ThreadRange(1, 8);
  276. ADD_CASES(TC_ConsoleOut, {{"^BM_Counters_AvgThreads/threads:%int "
  277. "%console_report bar=%hrfloat foo=%hrfloat$"}});
  278. ADD_CASES(TC_JSONOut,
  279. {{"\"name\": \"BM_Counters_AvgThreads/threads:%int\",$"},
  280. {"\"family_index\": 6,$", MR_Next},
  281. {"\"per_family_instance_index\": 0,$", MR_Next},
  282. {"\"run_name\": \"BM_Counters_AvgThreads/threads:%int\",$", MR_Next},
  283. {"\"run_type\": \"iteration\",$", MR_Next},
  284. {"\"repetitions\": 1,$", MR_Next},
  285. {"\"repetition_index\": 0,$", MR_Next},
  286. {"\"threads\": 1,$", MR_Next},
  287. {"\"iterations\": %int,$", MR_Next},
  288. {"\"real_time\": %float,$", MR_Next},
  289. {"\"cpu_time\": %float,$", MR_Next},
  290. {"\"time_unit\": \"ns\",$", MR_Next},
  291. {"\"bar\": %float,$", MR_Next},
  292. {"\"foo\": %float$", MR_Next},
  293. {"}", MR_Next}});
  294. ADD_CASES(
  295. TC_CSVOut,
  296. {{"^\"BM_Counters_AvgThreads/threads:%int\",%csv_report,%float,%float$"}});
  297. // VS2013 does not allow this function to be passed as a lambda argument
  298. // to CHECK_BENCHMARK_RESULTS()
  299. void CheckAvgThreads(Results const& e) {
  300. CHECK_COUNTER_VALUE(e, int, "foo", EQ, 1);
  301. CHECK_COUNTER_VALUE(e, int, "bar", EQ, 2);
  302. }
  303. CHECK_BENCHMARK_RESULTS("BM_Counters_AvgThreads/threads:%int",
  304. &CheckAvgThreads);
  305. // ========================================================================= //
  306. // ---------------------- ThreadAvg Counters Output ------------------------ //
  307. // ========================================================================= //
  308. void BM_Counters_AvgThreadsRate(benchmark::State& state) {
  309. for (auto _ : state) {
  310. // This test requires a non-zero CPU time to avoid divide-by-zero
  311. benchmark::DoNotOptimize(state.iterations());
  312. }
  313. namespace bm = benchmark;
  314. state.counters["foo"] = bm::Counter{1, bm::Counter::kAvgThreadsRate};
  315. state.counters["bar"] = bm::Counter{2, bm::Counter::kAvgThreadsRate};
  316. }
  317. BENCHMARK(BM_Counters_AvgThreadsRate)->ThreadRange(1, 8);
  318. ADD_CASES(TC_ConsoleOut, {{"^BM_Counters_AvgThreadsRate/threads:%int "
  319. "%console_report bar=%hrfloat/s foo=%hrfloat/s$"}});
  320. ADD_CASES(TC_JSONOut,
  321. {{"\"name\": \"BM_Counters_AvgThreadsRate/threads:%int\",$"},
  322. {"\"family_index\": 7,$", MR_Next},
  323. {"\"per_family_instance_index\": 0,$", MR_Next},
  324. {"\"run_name\": \"BM_Counters_AvgThreadsRate/threads:%int\",$",
  325. MR_Next},
  326. {"\"run_type\": \"iteration\",$", MR_Next},
  327. {"\"repetitions\": 1,$", MR_Next},
  328. {"\"repetition_index\": 0,$", MR_Next},
  329. {"\"threads\": 1,$", MR_Next},
  330. {"\"iterations\": %int,$", MR_Next},
  331. {"\"real_time\": %float,$", MR_Next},
  332. {"\"cpu_time\": %float,$", MR_Next},
  333. {"\"time_unit\": \"ns\",$", MR_Next},
  334. {"\"bar\": %float,$", MR_Next},
  335. {"\"foo\": %float$", MR_Next},
  336. {"}", MR_Next}});
  337. ADD_CASES(TC_CSVOut, {{"^\"BM_Counters_AvgThreadsRate/"
  338. "threads:%int\",%csv_report,%float,%float$"}});
  339. // VS2013 does not allow this function to be passed as a lambda argument
  340. // to CHECK_BENCHMARK_RESULTS()
  341. void CheckAvgThreadsRate(Results const& e) {
  342. CHECK_FLOAT_COUNTER_VALUE(e, "foo", EQ, 1. / e.DurationCPUTime(), 0.001);
  343. CHECK_FLOAT_COUNTER_VALUE(e, "bar", EQ, 2. / e.DurationCPUTime(), 0.001);
  344. }
  345. CHECK_BENCHMARK_RESULTS("BM_Counters_AvgThreadsRate/threads:%int",
  346. &CheckAvgThreadsRate);
  347. // ========================================================================= //
  348. // ------------------- IterationInvariant Counters Output ------------------ //
  349. // ========================================================================= //
  350. void BM_Counters_IterationInvariant(benchmark::State& state) {
  351. for (auto _ : state) {
  352. }
  353. namespace bm = benchmark;
  354. state.counters["foo"] = bm::Counter{1, bm::Counter::kIsIterationInvariant};
  355. state.counters["bar"] = bm::Counter{2, bm::Counter::kIsIterationInvariant};
  356. }
  357. BENCHMARK(BM_Counters_IterationInvariant);
  358. ADD_CASES(TC_ConsoleOut, {{"^BM_Counters_IterationInvariant %console_report "
  359. "bar=%hrfloat foo=%hrfloat$"}});
  360. ADD_CASES(TC_JSONOut,
  361. {{"\"name\": \"BM_Counters_IterationInvariant\",$"},
  362. {"\"family_index\": 8,$", MR_Next},
  363. {"\"per_family_instance_index\": 0,$", MR_Next},
  364. {"\"run_name\": \"BM_Counters_IterationInvariant\",$", MR_Next},
  365. {"\"run_type\": \"iteration\",$", MR_Next},
  366. {"\"repetitions\": 1,$", MR_Next},
  367. {"\"repetition_index\": 0,$", MR_Next},
  368. {"\"threads\": 1,$", MR_Next},
  369. {"\"iterations\": %int,$", MR_Next},
  370. {"\"real_time\": %float,$", MR_Next},
  371. {"\"cpu_time\": %float,$", MR_Next},
  372. {"\"time_unit\": \"ns\",$", MR_Next},
  373. {"\"bar\": %float,$", MR_Next},
  374. {"\"foo\": %float$", MR_Next},
  375. {"}", MR_Next}});
  376. ADD_CASES(TC_CSVOut,
  377. {{"^\"BM_Counters_IterationInvariant\",%csv_report,%float,%float$"}});
  378. // VS2013 does not allow this function to be passed as a lambda argument
  379. // to CHECK_BENCHMARK_RESULTS()
  380. void CheckIterationInvariant(Results const& e) {
  381. double its = e.NumIterations();
  382. // check that the values are within 0.1% of the expected value
  383. CHECK_FLOAT_COUNTER_VALUE(e, "foo", EQ, its, 0.001);
  384. CHECK_FLOAT_COUNTER_VALUE(e, "bar", EQ, 2. * its, 0.001);
  385. }
  386. CHECK_BENCHMARK_RESULTS("BM_Counters_IterationInvariant",
  387. &CheckIterationInvariant);
  388. // ========================================================================= //
  389. // ----------------- IterationInvariantRate Counters Output ---------------- //
  390. // ========================================================================= //
  391. void BM_Counters_kIsIterationInvariantRate(benchmark::State& state) {
  392. for (auto _ : state) {
  393. // This test requires a non-zero CPU time to avoid divide-by-zero
  394. benchmark::DoNotOptimize(state.iterations());
  395. }
  396. namespace bm = benchmark;
  397. state.counters["foo"] =
  398. bm::Counter{1, bm::Counter::kIsIterationInvariantRate};
  399. state.counters["bar"] =
  400. bm::Counter{2, bm::Counter::kIsRate | bm::Counter::kIsIterationInvariant};
  401. }
  402. BENCHMARK(BM_Counters_kIsIterationInvariantRate);
  403. ADD_CASES(TC_ConsoleOut, {{"^BM_Counters_kIsIterationInvariantRate "
  404. "%console_report bar=%hrfloat/s foo=%hrfloat/s$"}});
  405. ADD_CASES(TC_JSONOut,
  406. {{"\"name\": \"BM_Counters_kIsIterationInvariantRate\",$"},
  407. {"\"family_index\": 9,$", MR_Next},
  408. {"\"per_family_instance_index\": 0,$", MR_Next},
  409. {"\"run_name\": \"BM_Counters_kIsIterationInvariantRate\",$",
  410. MR_Next},
  411. {"\"run_type\": \"iteration\",$", MR_Next},
  412. {"\"repetitions\": 1,$", MR_Next},
  413. {"\"repetition_index\": 0,$", MR_Next},
  414. {"\"threads\": 1,$", MR_Next},
  415. {"\"iterations\": %int,$", MR_Next},
  416. {"\"real_time\": %float,$", MR_Next},
  417. {"\"cpu_time\": %float,$", MR_Next},
  418. {"\"time_unit\": \"ns\",$", MR_Next},
  419. {"\"bar\": %float,$", MR_Next},
  420. {"\"foo\": %float$", MR_Next},
  421. {"}", MR_Next}});
  422. ADD_CASES(TC_CSVOut, {{"^\"BM_Counters_kIsIterationInvariantRate\",%csv_report,"
  423. "%float,%float$"}});
  424. // VS2013 does not allow this function to be passed as a lambda argument
  425. // to CHECK_BENCHMARK_RESULTS()
  426. void CheckIsIterationInvariantRate(Results const& e) {
  427. double its = e.NumIterations();
  428. double t = e.DurationCPUTime(); // this (and not real time) is the time used
  429. // check that the values are within 0.1% of the expected values
  430. CHECK_FLOAT_COUNTER_VALUE(e, "foo", EQ, its * 1. / t, 0.001);
  431. CHECK_FLOAT_COUNTER_VALUE(e, "bar", EQ, its * 2. / t, 0.001);
  432. }
  433. CHECK_BENCHMARK_RESULTS("BM_Counters_kIsIterationInvariantRate",
  434. &CheckIsIterationInvariantRate);
  435. // ========================================================================= //
  436. // ------------------- AvgIterations Counters Output ------------------ //
  437. // ========================================================================= //
  438. void BM_Counters_AvgIterations(benchmark::State& state) {
  439. for (auto _ : state) {
  440. }
  441. namespace bm = benchmark;
  442. state.counters["foo"] = bm::Counter{1, bm::Counter::kAvgIterations};
  443. state.counters["bar"] = bm::Counter{2, bm::Counter::kAvgIterations};
  444. }
  445. BENCHMARK(BM_Counters_AvgIterations);
  446. ADD_CASES(TC_ConsoleOut, {{"^BM_Counters_AvgIterations %console_report "
  447. "bar=%hrfloat foo=%hrfloat$"}});
  448. ADD_CASES(TC_JSONOut,
  449. {{"\"name\": \"BM_Counters_AvgIterations\",$"},
  450. {"\"family_index\": 10,$", MR_Next},
  451. {"\"per_family_instance_index\": 0,$", MR_Next},
  452. {"\"run_name\": \"BM_Counters_AvgIterations\",$", MR_Next},
  453. {"\"run_type\": \"iteration\",$", MR_Next},
  454. {"\"repetitions\": 1,$", MR_Next},
  455. {"\"repetition_index\": 0,$", MR_Next},
  456. {"\"threads\": 1,$", MR_Next},
  457. {"\"iterations\": %int,$", MR_Next},
  458. {"\"real_time\": %float,$", MR_Next},
  459. {"\"cpu_time\": %float,$", MR_Next},
  460. {"\"time_unit\": \"ns\",$", MR_Next},
  461. {"\"bar\": %float,$", MR_Next},
  462. {"\"foo\": %float$", MR_Next},
  463. {"}", MR_Next}});
  464. ADD_CASES(TC_CSVOut,
  465. {{"^\"BM_Counters_AvgIterations\",%csv_report,%float,%float$"}});
  466. // VS2013 does not allow this function to be passed as a lambda argument
  467. // to CHECK_BENCHMARK_RESULTS()
  468. void CheckAvgIterations(Results const& e) {
  469. double its = e.NumIterations();
  470. // check that the values are within 0.1% of the expected value
  471. CHECK_FLOAT_COUNTER_VALUE(e, "foo", EQ, 1. / its, 0.001);
  472. CHECK_FLOAT_COUNTER_VALUE(e, "bar", EQ, 2. / its, 0.001);
  473. }
  474. CHECK_BENCHMARK_RESULTS("BM_Counters_AvgIterations", &CheckAvgIterations);
  475. // ========================================================================= //
  476. // ----------------- AvgIterationsRate Counters Output ---------------- //
  477. // ========================================================================= //
  478. void BM_Counters_kAvgIterationsRate(benchmark::State& state) {
  479. for (auto _ : state) {
  480. // This test requires a non-zero CPU time to avoid divide-by-zero
  481. benchmark::DoNotOptimize(state.iterations());
  482. }
  483. namespace bm = benchmark;
  484. state.counters["foo"] = bm::Counter{1, bm::Counter::kAvgIterationsRate};
  485. state.counters["bar"] =
  486. bm::Counter{2, bm::Counter::kIsRate | bm::Counter::kAvgIterations};
  487. }
  488. BENCHMARK(BM_Counters_kAvgIterationsRate);
  489. ADD_CASES(TC_ConsoleOut, {{"^BM_Counters_kAvgIterationsRate "
  490. "%console_report bar=%hrfloat/s foo=%hrfloat/s$"}});
  491. ADD_CASES(TC_JSONOut,
  492. {{"\"name\": \"BM_Counters_kAvgIterationsRate\",$"},
  493. {"\"family_index\": 11,$", MR_Next},
  494. {"\"per_family_instance_index\": 0,$", MR_Next},
  495. {"\"run_name\": \"BM_Counters_kAvgIterationsRate\",$", MR_Next},
  496. {"\"run_type\": \"iteration\",$", MR_Next},
  497. {"\"repetitions\": 1,$", MR_Next},
  498. {"\"repetition_index\": 0,$", MR_Next},
  499. {"\"threads\": 1,$", MR_Next},
  500. {"\"iterations\": %int,$", MR_Next},
  501. {"\"real_time\": %float,$", MR_Next},
  502. {"\"cpu_time\": %float,$", MR_Next},
  503. {"\"time_unit\": \"ns\",$", MR_Next},
  504. {"\"bar\": %float,$", MR_Next},
  505. {"\"foo\": %float$", MR_Next},
  506. {"}", MR_Next}});
  507. ADD_CASES(TC_CSVOut, {{"^\"BM_Counters_kAvgIterationsRate\",%csv_report,"
  508. "%float,%float$"}});
  509. // VS2013 does not allow this function to be passed as a lambda argument
  510. // to CHECK_BENCHMARK_RESULTS()
  511. void CheckAvgIterationsRate(Results const& e) {
  512. double its = e.NumIterations();
  513. double t = e.DurationCPUTime(); // this (and not real time) is the time used
  514. // check that the values are within 0.1% of the expected values
  515. CHECK_FLOAT_COUNTER_VALUE(e, "foo", EQ, 1. / its / t, 0.001);
  516. CHECK_FLOAT_COUNTER_VALUE(e, "bar", EQ, 2. / its / t, 0.001);
  517. }
  518. CHECK_BENCHMARK_RESULTS("BM_Counters_kAvgIterationsRate",
  519. &CheckAvgIterationsRate);
  520. // ========================================================================= //
  521. // --------------------------- TEST CASES END ------------------------------ //
  522. // ========================================================================= //
  523. int main(int argc, char* argv[]) { RunOutputTests(argc, argv); }