1 | #include <cstdarg> |
2 | #undef NDEBUG |
3 | |
4 | #include "../src/commandlineflags.h" |
5 | #include "../src/perf_counters.h" |
6 | #include "benchmark/benchmark.h" |
7 | #include "output_test.h" |
8 | |
9 | namespace benchmark { |
10 | |
11 | BM_DECLARE_string(benchmark_perf_counters); |
12 | |
13 | } // namespace benchmark |
14 | |
15 | static void BM_Simple(benchmark::State& state) { |
16 | for (auto _ : state) { |
17 | auto iterations = double(state.iterations()) * double(state.iterations()); |
18 | benchmark::DoNotOptimize(value&: iterations); |
19 | } |
20 | } |
21 | BENCHMARK(BM_Simple); |
22 | ADD_CASES(TC_JSONOut, {{"\"name\": \"BM_Simple\",$" }}); |
23 | |
24 | const int kIters = 1000000; |
25 | |
26 | void BM_WithoutPauseResume(benchmark::State& state) { |
27 | int n = 0; |
28 | |
29 | for (auto _ : state) { |
30 | for (auto i = 0; i < kIters; ++i) { |
31 | n = 1 - n; |
32 | benchmark::DoNotOptimize(value&: n); |
33 | } |
34 | } |
35 | } |
36 | |
37 | BENCHMARK(BM_WithoutPauseResume); |
38 | ADD_CASES(TC_JSONOut, {{"\"name\": \"BM_WithoutPauseResume\",$" }}); |
39 | |
40 | void BM_WithPauseResume(benchmark::State& state) { |
41 | int m = 0, n = 0; |
42 | |
43 | for (auto _ : state) { |
44 | for (auto i = 0; i < kIters; ++i) { |
45 | n = 1 - n; |
46 | benchmark::DoNotOptimize(value&: n); |
47 | } |
48 | |
49 | state.PauseTiming(); |
50 | for (auto j = 0; j < kIters; ++j) { |
51 | m = 1 - m; |
52 | benchmark::DoNotOptimize(value&: m); |
53 | } |
54 | state.ResumeTiming(); |
55 | } |
56 | } |
57 | |
58 | BENCHMARK(BM_WithPauseResume); |
59 | |
60 | ADD_CASES(TC_JSONOut, {{"\"name\": \"BM_WithPauseResume\",$" }}); |
61 | |
62 | static void CheckSimple(Results const& e) { |
63 | CHECK_COUNTER_VALUE(e, double, "CYCLES" , GT, 0); |
64 | } |
65 | |
66 | double withoutPauseResumeInstrCount = 0.0; |
67 | double withPauseResumeInstrCount = 0.0; |
68 | |
69 | static void SaveInstrCountWithoutResume(Results const& e) { |
70 | withoutPauseResumeInstrCount = e.GetAs<double>(entry_name: "INSTRUCTIONS" ); |
71 | } |
72 | |
73 | static void SaveInstrCountWithResume(Results const& e) { |
74 | withPauseResumeInstrCount = e.GetAs<double>(entry_name: "INSTRUCTIONS" ); |
75 | } |
76 | |
77 | CHECK_BENCHMARK_RESULTS("BM_Simple" , &CheckSimple); |
78 | CHECK_BENCHMARK_RESULTS("BM_WithoutPauseResume" , &SaveInstrCountWithoutResume); |
79 | CHECK_BENCHMARK_RESULTS("BM_WithPauseResume" , &SaveInstrCountWithResume); |
80 | |
81 | int main(int argc, char* argv[]) { |
82 | if (!benchmark::internal::PerfCounters::kSupported) { |
83 | return 0; |
84 | } |
85 | benchmark::FLAGS_benchmark_perf_counters = "CYCLES,INSTRUCTIONS" ; |
86 | benchmark::internal::PerfCounters::Initialize(); |
87 | RunOutputTests(argc, argv); |
88 | |
89 | BM_CHECK_GT(withPauseResumeInstrCount, kIters); |
90 | BM_CHECK_GT(withoutPauseResumeInstrCount, kIters); |
91 | BM_CHECK_LT(withPauseResumeInstrCount, 1.5 * withoutPauseResumeInstrCount); |
92 | } |
93 | |