mirror of https://github.com/google/benchmark.git
Include system load average in console and JSON reports
High system load can skew benchmark results. By including system load averages in the library's output, we help users identify a potential issue in the quality of their measurements, and thus assist them in producing better (more reproducible) results. I got the idea for this from Brendan Gregg's checklist for benchmark accuracy (http://www.brendangregg.com/blog/2018-06-30/benchmarking-checklist.html).
This commit is contained in:
parent
1f35fa4aa7
commit
da9ec3dfca
|
@ -1242,6 +1242,7 @@ struct CPUInfo {
|
|||
double cycles_per_second;
|
||||
std::vector<CacheInfo> caches;
|
||||
bool scaling_enabled;
|
||||
std::vector<double> load_avg;
|
||||
|
||||
static const CPUInfo& Get();
|
||||
|
||||
|
|
|
@ -111,6 +111,12 @@ bool JSONReporter::ReportContext(const Context& context) {
|
|||
}
|
||||
indent = std::string(4, ' ');
|
||||
out << indent << "],\n";
|
||||
out << indent << "\"load_avg\": [";
|
||||
for (auto it = info.load_avg.begin(); it != info.load_avg.end();) {
|
||||
out << *it++;
|
||||
if (it != info.load_avg.end()) out << ",";
|
||||
}
|
||||
out << "],\n";
|
||||
|
||||
#if defined(NDEBUG)
|
||||
const char build_type[] = "release";
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include <vector>
|
||||
|
||||
#include "check.h"
|
||||
#include "string_util.h"
|
||||
|
||||
namespace benchmark {
|
||||
|
||||
|
@ -54,6 +55,14 @@ void BenchmarkReporter::PrintBasicContext(std::ostream *out,
|
|||
Out << "\n";
|
||||
}
|
||||
}
|
||||
if (!info.load_avg.empty()) {
|
||||
Out << "Load Average: ";
|
||||
for (auto It = info.load_avg.begin(); It != info.load_avg.end();) {
|
||||
Out << StrFormat("%.2f", *It++);
|
||||
if (It != info.load_avg.end()) Out << ", ";
|
||||
}
|
||||
Out << "\n";
|
||||
}
|
||||
|
||||
if (info.scaling_enabled) {
|
||||
Out << "***WARNING*** CPU scaling is enabled, the benchmark "
|
||||
|
|
|
@ -571,6 +571,24 @@ double GetCPUCyclesPerSecond() {
|
|||
return static_cast<double>(cycleclock::Now() - start_ticks);
|
||||
}
|
||||
|
||||
std::vector<double> GetLoadAvg() {
|
||||
#if defined BENCHMARK_OS_FREEBSD || defined(BENCHMARK_OS_LINUX) || \
|
||||
defined BENCHMARK_OS_MACOSX || defined BENCHMARK_OS_NETBSD || \
|
||||
defined BENCHMARK_OS_OPENBSD
|
||||
constexpr int kMaxSamples = 3;
|
||||
std::vector<double> res(kMaxSamples, 0.0);
|
||||
const int nelem = getloadavg(res.data(), kMaxSamples);
|
||||
if (nelem < 1) {
|
||||
res.clear();
|
||||
} else {
|
||||
res.resize(nelem);
|
||||
}
|
||||
return res;
|
||||
#else
|
||||
return {};
|
||||
#endif
|
||||
}
|
||||
|
||||
} // end namespace
|
||||
|
||||
const CPUInfo& CPUInfo::Get() {
|
||||
|
@ -582,6 +600,7 @@ CPUInfo::CPUInfo()
|
|||
: num_cpus(GetNumCPUs()),
|
||||
cycles_per_second(GetCPUCyclesPerSecond()),
|
||||
caches(GetCacheSizes()),
|
||||
scaling_enabled(CpuScalingEnabled(num_cpus)) {}
|
||||
scaling_enabled(CpuScalingEnabled(num_cpus)),
|
||||
load_avg(GetLoadAvg()) {}
|
||||
|
||||
} // end namespace benchmark
|
||||
|
|
|
@ -28,7 +28,8 @@ static int AddContextCases() {
|
|||
{"\"mhz_per_cpu\": %float,$", MR_Next},
|
||||
{"\"cpu_scaling_enabled\": ", MR_Next},
|
||||
{"\"caches\": \\[$", MR_Next}});
|
||||
auto const& Caches = benchmark::CPUInfo::Get().caches;
|
||||
auto const& Info = benchmark::CPUInfo::Get();
|
||||
auto const& Caches = Info.caches;
|
||||
if (!Caches.empty()) {
|
||||
AddCases(TC_ConsoleErr, {{"CPU Caches:$", MR_Next}});
|
||||
}
|
||||
|
@ -45,8 +46,13 @@ static int AddContextCases() {
|
|||
{"\"num_sharing\": %int$", MR_Next},
|
||||
{"}[,]{0,1}$", MR_Next}});
|
||||
}
|
||||
|
||||
AddCases(TC_JSONOut, {{"],$"}});
|
||||
auto const& LoadAvg = Info.load_avg;
|
||||
if (!LoadAvg.empty()) {
|
||||
AddCases(TC_ConsoleErr,
|
||||
{{"Load Average: (%float, ){0,2}%float$", MR_Next}});
|
||||
}
|
||||
AddCases(TC_JSONOut, {{"\"load_avg\": \\[(%float,?){0,3}],$", MR_Next}});
|
||||
return 0;
|
||||
}
|
||||
int dummy_register = AddContextCases();
|
||||
|
|
Loading…
Reference in New Issue