1a8c51b3fSopenharmony_ci// Copyright 2015 Google Inc. All rights reserved.
2a8c51b3fSopenharmony_ci//
3a8c51b3fSopenharmony_ci// Licensed under the Apache License, Version 2.0 (the "License");
4a8c51b3fSopenharmony_ci// you may not use this file except in compliance with the License.
5a8c51b3fSopenharmony_ci// You may obtain a copy of the License at
6a8c51b3fSopenharmony_ci//
7a8c51b3fSopenharmony_ci//     http://www.apache.org/licenses/LICENSE-2.0
8a8c51b3fSopenharmony_ci//
9a8c51b3fSopenharmony_ci// Unless required by applicable law or agreed to in writing, software
10a8c51b3fSopenharmony_ci// distributed under the License is distributed on an "AS IS" BASIS,
11a8c51b3fSopenharmony_ci// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12a8c51b3fSopenharmony_ci// See the License for the specific language governing permissions and
13a8c51b3fSopenharmony_ci// limitations under the License.
14a8c51b3fSopenharmony_ci
15a8c51b3fSopenharmony_ci#include <cstdlib>
16a8c51b3fSopenharmony_ci#include <iostream>
17a8c51b3fSopenharmony_ci#include <map>
18a8c51b3fSopenharmony_ci#include <string>
19a8c51b3fSopenharmony_ci#include <tuple>
20a8c51b3fSopenharmony_ci#include <vector>
21a8c51b3fSopenharmony_ci
22a8c51b3fSopenharmony_ci#include "benchmark/benchmark.h"
23a8c51b3fSopenharmony_ci#include "check.h"
24a8c51b3fSopenharmony_ci#include "string_util.h"
25a8c51b3fSopenharmony_ci#include "timers.h"
26a8c51b3fSopenharmony_ci
27a8c51b3fSopenharmony_cinamespace benchmark {
28a8c51b3fSopenharmony_ci
29a8c51b3fSopenharmony_ciBenchmarkReporter::BenchmarkReporter()
30a8c51b3fSopenharmony_ci    : output_stream_(&std::cout), error_stream_(&std::cerr) {}
31a8c51b3fSopenharmony_ci
32a8c51b3fSopenharmony_ciBenchmarkReporter::~BenchmarkReporter() {}
33a8c51b3fSopenharmony_ci
34a8c51b3fSopenharmony_civoid BenchmarkReporter::PrintBasicContext(std::ostream *out,
35a8c51b3fSopenharmony_ci                                          Context const &context) {
36a8c51b3fSopenharmony_ci  BM_CHECK(out) << "cannot be null";
37a8c51b3fSopenharmony_ci  auto &Out = *out;
38a8c51b3fSopenharmony_ci
39a8c51b3fSopenharmony_ci#ifndef BENCHMARK_OS_QURT
40a8c51b3fSopenharmony_ci  // Date/time information is not available on QuRT.
41a8c51b3fSopenharmony_ci  // Attempting to get it via this call cause the binary to crash.
42a8c51b3fSopenharmony_ci  Out << LocalDateTimeString() << "\n";
43a8c51b3fSopenharmony_ci#endif
44a8c51b3fSopenharmony_ci
45a8c51b3fSopenharmony_ci  if (context.executable_name)
46a8c51b3fSopenharmony_ci    Out << "Running " << context.executable_name << "\n";
47a8c51b3fSopenharmony_ci
48a8c51b3fSopenharmony_ci  const CPUInfo &info = context.cpu_info;
49a8c51b3fSopenharmony_ci  Out << "Run on (" << info.num_cpus << " X "
50a8c51b3fSopenharmony_ci      << (info.cycles_per_second / 1000000.0) << " MHz CPU "
51a8c51b3fSopenharmony_ci      << ((info.num_cpus > 1) ? "s" : "") << ")\n";
52a8c51b3fSopenharmony_ci  if (info.caches.size() != 0) {
53a8c51b3fSopenharmony_ci    Out << "CPU Caches:\n";
54a8c51b3fSopenharmony_ci    for (auto &CInfo : info.caches) {
55a8c51b3fSopenharmony_ci      Out << "  L" << CInfo.level << " " << CInfo.type << " "
56a8c51b3fSopenharmony_ci          << (CInfo.size / 1024) << " KiB";
57a8c51b3fSopenharmony_ci      if (CInfo.num_sharing != 0)
58a8c51b3fSopenharmony_ci        Out << " (x" << (info.num_cpus / CInfo.num_sharing) << ")";
59a8c51b3fSopenharmony_ci      Out << "\n";
60a8c51b3fSopenharmony_ci    }
61a8c51b3fSopenharmony_ci  }
62a8c51b3fSopenharmony_ci  if (!info.load_avg.empty()) {
63a8c51b3fSopenharmony_ci    Out << "Load Average: ";
64a8c51b3fSopenharmony_ci    for (auto It = info.load_avg.begin(); It != info.load_avg.end();) {
65a8c51b3fSopenharmony_ci      Out << StrFormat("%.2f", *It++);
66a8c51b3fSopenharmony_ci      if (It != info.load_avg.end()) Out << ", ";
67a8c51b3fSopenharmony_ci    }
68a8c51b3fSopenharmony_ci    Out << "\n";
69a8c51b3fSopenharmony_ci  }
70a8c51b3fSopenharmony_ci
71a8c51b3fSopenharmony_ci  std::map<std::string, std::string> *global_context =
72a8c51b3fSopenharmony_ci      internal::GetGlobalContext();
73a8c51b3fSopenharmony_ci
74a8c51b3fSopenharmony_ci  if (global_context != nullptr) {
75a8c51b3fSopenharmony_ci    for (const auto &kv : *global_context) {
76a8c51b3fSopenharmony_ci      Out << kv.first << ": " << kv.second << "\n";
77a8c51b3fSopenharmony_ci    }
78a8c51b3fSopenharmony_ci  }
79a8c51b3fSopenharmony_ci
80a8c51b3fSopenharmony_ci  if (CPUInfo::Scaling::ENABLED == info.scaling) {
81a8c51b3fSopenharmony_ci    Out << "***WARNING*** CPU scaling is enabled, the benchmark "
82a8c51b3fSopenharmony_ci           "real time measurements may be noisy and will incur extra "
83a8c51b3fSopenharmony_ci           "overhead.\n";
84a8c51b3fSopenharmony_ci  }
85a8c51b3fSopenharmony_ci
86a8c51b3fSopenharmony_ci#ifndef NDEBUG
87a8c51b3fSopenharmony_ci  Out << "***WARNING*** Library was built as DEBUG. Timings may be "
88a8c51b3fSopenharmony_ci         "affected.\n";
89a8c51b3fSopenharmony_ci#endif
90a8c51b3fSopenharmony_ci}
91a8c51b3fSopenharmony_ci
92a8c51b3fSopenharmony_ci// No initializer because it's already initialized to NULL.
93a8c51b3fSopenharmony_ciconst char *BenchmarkReporter::Context::executable_name;
94a8c51b3fSopenharmony_ci
95a8c51b3fSopenharmony_ciBenchmarkReporter::Context::Context()
96a8c51b3fSopenharmony_ci    : cpu_info(CPUInfo::Get()), sys_info(SystemInfo::Get()) {}
97a8c51b3fSopenharmony_ci
98a8c51b3fSopenharmony_cistd::string BenchmarkReporter::Run::benchmark_name() const {
99a8c51b3fSopenharmony_ci  std::string name = run_name.str();
100a8c51b3fSopenharmony_ci  if (run_type == RT_Aggregate) {
101a8c51b3fSopenharmony_ci    name += "_" + aggregate_name;
102a8c51b3fSopenharmony_ci  }
103a8c51b3fSopenharmony_ci  return name;
104a8c51b3fSopenharmony_ci}
105a8c51b3fSopenharmony_ci
106a8c51b3fSopenharmony_cidouble BenchmarkReporter::Run::GetAdjustedRealTime() const {
107a8c51b3fSopenharmony_ci  double new_time = real_accumulated_time * GetTimeUnitMultiplier(time_unit);
108a8c51b3fSopenharmony_ci  if (iterations != 0) new_time /= static_cast<double>(iterations);
109a8c51b3fSopenharmony_ci  return new_time;
110a8c51b3fSopenharmony_ci}
111a8c51b3fSopenharmony_ci
112a8c51b3fSopenharmony_cidouble BenchmarkReporter::Run::GetAdjustedCPUTime() const {
113a8c51b3fSopenharmony_ci  double new_time = cpu_accumulated_time * GetTimeUnitMultiplier(time_unit);
114a8c51b3fSopenharmony_ci  if (iterations != 0) new_time /= static_cast<double>(iterations);
115a8c51b3fSopenharmony_ci  return new_time;
116a8c51b3fSopenharmony_ci}
117a8c51b3fSopenharmony_ci
118a8c51b3fSopenharmony_ci}  // end namespace benchmark
119