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