1819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn/*
2819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn * Copyright (C) 2012-2014 The Android Open Source Project
3819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn *
4819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn * Licensed under the Apache License, Version 2.0 (the "License");
5819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn * you may not use this file except in compliance with the License.
6819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn * You may obtain a copy of the License at
7819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn *
8819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn *      http://www.apache.org/licenses/LICENSE-2.0
9819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn *
10819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn * Unless required by applicable law or agreed to in writing, software
11819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn * distributed under the License is distributed on an "AS IS" BASIS,
12819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn * See the License for the specific language governing permissions and
14819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn * limitations under the License.
15819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn */
16819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn
17819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn#include <benchmark.h>
18819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn
195d9fe779c8ec2705865a23061834ad8cdbee5b82Elliott Hughes#include <inttypes.h>
20f2dedb7a5f07dc5e0b814c82739aeb0097cf86faDan Albert#include <math.h>
21819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn#include <regex.h>
22819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn#include <stdio.h>
23819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn#include <stdlib.h>
24819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn
25819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn#include <map>
262ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn#include <string>
27819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn#include <vector>
28819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn
29819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzynstatic uint64_t gBytesProcessed;
30819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzynstatic uint64_t gBenchmarkTotalTimeNs;
31819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzynstatic uint64_t gBenchmarkTotalTimeNsSquared;
32819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzynstatic uint64_t gBenchmarkNum;
33819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzynstatic uint64_t gBenchmarkStartTimeNs;
34819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn
352ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyntypedef std::vector< ::testing::Benchmark*> BenchmarkList;
36819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzynstatic BenchmarkList* gBenchmarks;
37819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn
38819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzynstatic int Round(int n) {
39819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn  int base = 1;
402ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  while (base * 10 < n) {
41819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn    base *= 10;
42819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn  }
432ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  if (n < 2 * base) {
442ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    return 2 * base;
45819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn  }
462ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  if (n < 5 * base) {
472ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    return 5 * base;
48819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn  }
492ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  return 10 * base;
50819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn}
51819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn
52819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzynstatic uint64_t NanoTime() {
53819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn  struct timespec t;
54819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn  t.tv_sec = t.tv_nsec = 0;
55819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn  clock_gettime(CLOCK_MONOTONIC, &t);
56819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn  return static_cast<uint64_t>(t.tv_sec) * 1000000000ULL + t.tv_nsec;
57819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn}
58819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn
59819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzynnamespace testing {
60819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn
612ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzynint PrettyPrintInt(char* str, int len, unsigned int arg) {
622ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  if (arg >= (1 << 30) && arg % (1 << 30) == 0) {
632ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    return snprintf(str, len, "%uGi", arg / (1 << 30));
642ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  } else if (arg >= (1 << 20) && arg % (1 << 20) == 0) {
652ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    return snprintf(str, len, "%uMi", arg / (1 << 20));
662ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  } else if (arg >= (1 << 10) && arg % (1 << 10) == 0) {
672ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    return snprintf(str, len, "%uKi", arg / (1 << 10));
68819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn  } else if (arg >= 1000000000 && arg % 1000000000 == 0) {
692ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    return snprintf(str, len, "%uG", arg / 1000000000);
70819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn  } else if (arg >= 1000000 && arg % 1000000 == 0) {
712ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    return snprintf(str, len, "%uM", arg / 1000000);
72819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn  } else if (arg >= 1000 && arg % 1000 == 0) {
732ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    return snprintf(str, len, "%uK", arg / 1000);
74819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn  } else {
75819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn    return snprintf(str, len, "%u", arg);
76819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn  }
77819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn}
78819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn
79819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzynbool ShouldRun(Benchmark* b, int argc, char* argv[]) {
80819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn  if (argc == 1) {
81819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn    return true;  // With no arguments, we run all benchmarks.
82819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn  }
83819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn  // Otherwise, we interpret each argument as a regular expression and
84819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn  // see if any of our benchmarks match.
85819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn  for (int i = 1; i < argc; i++) {
86819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn    regex_t re;
87819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn    if (regcomp(&re, argv[i], 0) != 0) {
882ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn      fprintf(stderr, "couldn't compile \"%s\" as a regular expression!\n",
892ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn              argv[i]);
90819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn      exit(EXIT_FAILURE);
91819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn    }
92819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn    int match = regexec(&re, b->Name(), 0, NULL, 0);
93819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn    regfree(&re);
94819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn    if (match != REG_NOMATCH) {
95819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn      return true;
96819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn    }
97819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn  }
98819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn  return false;
99819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn}
100819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn
101819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzynvoid BenchmarkRegister(Benchmark* b) {
102819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn  if (gBenchmarks == NULL) {
103819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn    gBenchmarks = new BenchmarkList;
104819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn  }
105819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn  gBenchmarks->push_back(b);
106819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn}
107819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn
108819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzynvoid RunRepeatedly(Benchmark* b, int iterations) {
109819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn  gBytesProcessed = 0;
110819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn  ResetBenchmarkTiming();
111819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn  uint64_t StartTimeNs = NanoTime();
112819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn  b->RunFn(iterations);
113819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn  // Catch us if we fail to log anything.
1142ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  if ((gBenchmarkTotalTimeNs == 0) && (StartTimeNs != 0) &&
1152ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn      (gBenchmarkStartTimeNs == 0)) {
116819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn    gBenchmarkTotalTimeNs = NanoTime() - StartTimeNs;
117819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn  }
118819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn}
119819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn
120819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzynvoid Run(Benchmark* b) {
121819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn  // run once in case it's expensive
122819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn  unsigned iterations = 1;
123819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn  uint64_t s = NanoTime();
124819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn  RunRepeatedly(b, iterations);
125819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn  s = NanoTime() - s;
126819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn  while (s < 2e9 && gBenchmarkTotalTimeNs < 1e9 && iterations < 1e9) {
127819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn    unsigned last = iterations;
1282ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    if (gBenchmarkTotalTimeNs / iterations == 0) {
129819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn      iterations = 1e9;
130819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn    } else {
1312ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn      iterations = 1e9 / (gBenchmarkTotalTimeNs / iterations);
132819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn    }
1332ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    iterations =
1342ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn        std::max(last + 1, std::min(iterations + iterations / 2, 100 * last));
135819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn    iterations = Round(iterations);
136819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn    s = NanoTime();
137819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn    RunRepeatedly(b, iterations);
138819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn    s = NanoTime() - s;
139819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn  }
140819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn
141819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn  char throughput[100];
142819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn  throughput[0] = '\0';
143819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn  if (gBenchmarkTotalTimeNs > 0 && gBytesProcessed > 0) {
1442ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    double mib_processed = static_cast<double>(gBytesProcessed) / 1e6;
1452ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    double seconds = static_cast<double>(gBenchmarkTotalTimeNs) / 1e9;
1462ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    snprintf(throughput, sizeof(throughput), " %8.2f MiB/s",
1472ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn             mib_processed / seconds);
148819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn  }
149819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn
150819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn  char full_name[100];
151819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn  snprintf(full_name, sizeof(full_name), "%s%s%s", b->Name(),
1522ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn           b->ArgName() ? "/" : "", b->ArgName() ? b->ArgName() : "");
153819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn
154819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn  uint64_t mean = gBenchmarkTotalTimeNs / iterations;
155819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn  uint64_t sdev = 0;
156819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn  if (gBenchmarkNum == iterations) {
157819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn    mean = gBenchmarkTotalTimeNs / gBenchmarkNum;
1582ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    uint64_t nXvariance = gBenchmarkTotalTimeNsSquared * gBenchmarkNum -
1592ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn                          (gBenchmarkTotalTimeNs * gBenchmarkTotalTimeNs);
160819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn    sdev = (sqrt((double)nXvariance) / gBenchmarkNum / gBenchmarkNum) + 0.5;
161819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn  }
162819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn  if (mean > (10000 * sdev)) {
1635d9fe779c8ec2705865a23061834ad8cdbee5b82Elliott Hughes    printf("%-25s %10" PRIu64 " %10" PRIu64 "%s\n", full_name,
1642ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn           static_cast<uint64_t>(iterations), mean, throughput);
165819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn  } else {
1662ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    printf("%-25s %10" PRIu64 " %10" PRIu64 "(\317\203%" PRIu64 ")%s\n",
1672ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn           full_name, static_cast<uint64_t>(iterations), mean, sdev, throughput);
168819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn  }
169819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn  fflush(stdout);
170819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn}
171819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn
172819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn}  // namespace testing
173819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn
174819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzynvoid SetBenchmarkBytesProcessed(uint64_t x) {
175819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn  gBytesProcessed = x;
176819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn}
177819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn
178819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzynvoid ResetBenchmarkTiming() {
179819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn  gBenchmarkStartTimeNs = 0;
180819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn  gBenchmarkTotalTimeNs = 0;
181819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn  gBenchmarkTotalTimeNsSquared = 0;
182819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn  gBenchmarkNum = 0;
183819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn}
184819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn
185819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzynvoid StopBenchmarkTiming(void) {
186819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn  if (gBenchmarkStartTimeNs != 0) {
187819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn    int64_t diff = NanoTime() - gBenchmarkStartTimeNs;
188819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn    gBenchmarkTotalTimeNs += diff;
189819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn    gBenchmarkTotalTimeNsSquared += diff * diff;
190819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn    ++gBenchmarkNum;
191819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn  }
192819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn  gBenchmarkStartTimeNs = 0;
193819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn}
194819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn
195819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzynvoid StartBenchmarkTiming(void) {
196819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn  if (gBenchmarkStartTimeNs == 0) {
197819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn    gBenchmarkStartTimeNs = NanoTime();
198819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn  }
199819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn}
200819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn
201819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzynvoid StopBenchmarkTiming(uint64_t NanoTime) {
202819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn  if (gBenchmarkStartTimeNs != 0) {
203819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn    int64_t diff = NanoTime - gBenchmarkStartTimeNs;
204819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn    gBenchmarkTotalTimeNs += diff;
205819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn    gBenchmarkTotalTimeNsSquared += diff * diff;
206819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn    if (NanoTime != 0) {
207819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn      ++gBenchmarkNum;
208819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn    }
209819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn  }
210819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn  gBenchmarkStartTimeNs = 0;
211819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn}
212819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn
213819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzynvoid StartBenchmarkTiming(uint64_t NanoTime) {
214819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn  if (gBenchmarkStartTimeNs == 0) {
215819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn    gBenchmarkStartTimeNs = NanoTime;
216819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn  }
217819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn}
218819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn
219819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzynint main(int argc, char* argv[]) {
220819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn  if (gBenchmarks->empty()) {
221819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn    fprintf(stderr, "No benchmarks registered!\n");
222819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn    exit(EXIT_FAILURE);
223819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn  }
224819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn
225819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn  bool need_header = true;
226819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn  for (auto b : *gBenchmarks) {
227819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn    if (ShouldRun(b, argc, argv)) {
228819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn      if (need_header) {
229819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn        printf("%-25s %10s %10s\n", "", "iterations", "ns/op");
230819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn        fflush(stdout);
231819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn        need_header = false;
232819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn      }
233819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn      Run(b);
234819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn    }
235819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn  }
236819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn
237819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn  if (need_header) {
238819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn    fprintf(stderr, "No matching benchmarks!\n");
239819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn    fprintf(stderr, "Available benchmarks:\n");
240819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn    for (auto b : *gBenchmarks) {
241819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn      fprintf(stderr, "  %s\n", b->Name());
242819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn    }
243819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn    exit(EXIT_FAILURE);
244819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn  }
245819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn
246819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn  return 0;
247819c58a8ca20f94700085b8967f371f5854a5216Mark Salyzyn}
248