⬆️ upgraded Catch and Google Benchmark
- Catch 1.12.0 -> 1.12.2 - Google Benchmark 1.3.0 -> 1.4.1
This commit is contained in:
parent
daeb48b01a
commit
06731b14d7
76 changed files with 2828 additions and 341 deletions
20
benchmarks/thirdparty/benchmark/src/CMakeLists.txt
vendored
Normal file → Executable file
20
benchmarks/thirdparty/benchmark/src/CMakeLists.txt
vendored
Normal file → Executable file
|
|
@ -11,6 +11,7 @@ file(GLOB
|
|||
*.cc
|
||||
${PROJECT_SOURCE_DIR}/include/benchmark/*.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/*.h)
|
||||
list(FILTER SOURCE_FILES EXCLUDE REGEX "benchmark_main\\.cc")
|
||||
|
||||
add_library(benchmark ${SOURCE_FILES})
|
||||
set_target_properties(benchmark PROPERTIES
|
||||
|
|
@ -34,6 +35,23 @@ if(${CMAKE_SYSTEM_NAME} MATCHES "Windows")
|
|||
target_link_libraries(benchmark Shlwapi)
|
||||
endif()
|
||||
|
||||
# We need extra libraries on Solaris
|
||||
if(${CMAKE_SYSTEM_NAME} MATCHES "SunOS")
|
||||
target_link_libraries(benchmark kstat)
|
||||
endif()
|
||||
|
||||
# Benchmark main library
|
||||
add_library(benchmark_main "benchmark_main.cc")
|
||||
set_target_properties(benchmark_main PROPERTIES
|
||||
OUTPUT_NAME "benchmark_main"
|
||||
VERSION ${GENERIC_LIB_VERSION}
|
||||
SOVERSION ${GENERIC_LIB_SOVERSION}
|
||||
)
|
||||
target_include_directories(benchmark PUBLIC
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/../include>
|
||||
)
|
||||
target_link_libraries(benchmark_main benchmark)
|
||||
|
||||
set(include_install_dir "include")
|
||||
set(lib_install_dir "lib/")
|
||||
set(bin_install_dir "bin/")
|
||||
|
|
@ -60,7 +78,7 @@ configure_file("${PROJECT_SOURCE_DIR}/cmake/benchmark.pc.in" "${pkg_config}" @ON
|
|||
if (BENCHMARK_ENABLE_INSTALL)
|
||||
# Install target (will install the library to specified CMAKE_INSTALL_PREFIX variable)
|
||||
install(
|
||||
TARGETS benchmark
|
||||
TARGETS benchmark benchmark_main
|
||||
EXPORT ${targets_export_name}
|
||||
ARCHIVE DESTINATION ${lib_install_dir}
|
||||
LIBRARY DESTINATION ${lib_install_dir}
|
||||
|
|
|
|||
0
benchmarks/thirdparty/benchmark/src/arraysize.h
vendored
Normal file → Executable file
0
benchmarks/thirdparty/benchmark/src/arraysize.h
vendored
Normal file → Executable file
174
benchmarks/thirdparty/benchmark/src/benchmark.cc
vendored
Normal file → Executable file
174
benchmarks/thirdparty/benchmark/src/benchmark.cc
vendored
Normal file → Executable file
|
|
@ -17,7 +17,9 @@
|
|||
#include "internal_macros.h"
|
||||
|
||||
#ifndef BENCHMARK_OS_WINDOWS
|
||||
#ifndef BENCHMARK_OS_FUCHSIA
|
||||
#include <sys/resource.h>
|
||||
#endif
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
|
@ -27,10 +29,10 @@
|
|||
#include <condition_variable>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <thread>
|
||||
|
||||
#include "check.h"
|
||||
|
|
@ -44,7 +46,8 @@
|
|||
#include "re.h"
|
||||
#include "statistics.h"
|
||||
#include "string_util.h"
|
||||
#include "timers.h"
|
||||
#include "thread_manager.h"
|
||||
#include "thread_timer.h"
|
||||
|
||||
DEFINE_bool(benchmark_list_tests, false,
|
||||
"Print a list of benchmarks. This option overrides all other "
|
||||
|
|
@ -82,7 +85,7 @@ DEFINE_string(benchmark_out_format, "json",
|
|||
"The format to use for file output. Valid values are "
|
||||
"'console', 'json', or 'csv'.");
|
||||
|
||||
DEFINE_string(benchmark_out, "", "The file to write additonal output to");
|
||||
DEFINE_string(benchmark_out, "", "The file to write additional output to");
|
||||
|
||||
DEFINE_string(benchmark_color, "auto",
|
||||
"Whether to use colors in the output. Valid values: "
|
||||
|
|
@ -108,118 +111,11 @@ namespace internal {
|
|||
|
||||
void UseCharPointer(char const volatile*) {}
|
||||
|
||||
class ThreadManager {
|
||||
public:
|
||||
ThreadManager(int num_threads)
|
||||
: alive_threads_(num_threads), start_stop_barrier_(num_threads) {}
|
||||
|
||||
Mutex& GetBenchmarkMutex() const RETURN_CAPABILITY(benchmark_mutex_) {
|
||||
return benchmark_mutex_;
|
||||
}
|
||||
|
||||
bool StartStopBarrier() EXCLUDES(end_cond_mutex_) {
|
||||
return start_stop_barrier_.wait();
|
||||
}
|
||||
|
||||
void NotifyThreadComplete() EXCLUDES(end_cond_mutex_) {
|
||||
start_stop_barrier_.removeThread();
|
||||
if (--alive_threads_ == 0) {
|
||||
MutexLock lock(end_cond_mutex_);
|
||||
end_condition_.notify_all();
|
||||
}
|
||||
}
|
||||
|
||||
void WaitForAllThreads() EXCLUDES(end_cond_mutex_) {
|
||||
MutexLock lock(end_cond_mutex_);
|
||||
end_condition_.wait(lock.native_handle(),
|
||||
[this]() { return alive_threads_ == 0; });
|
||||
}
|
||||
|
||||
public:
|
||||
struct Result {
|
||||
double real_time_used = 0;
|
||||
double cpu_time_used = 0;
|
||||
double manual_time_used = 0;
|
||||
int64_t bytes_processed = 0;
|
||||
int64_t items_processed = 0;
|
||||
int complexity_n = 0;
|
||||
std::string report_label_;
|
||||
std::string error_message_;
|
||||
bool has_error_ = false;
|
||||
UserCounters counters;
|
||||
};
|
||||
GUARDED_BY(GetBenchmarkMutex()) Result results;
|
||||
|
||||
private:
|
||||
mutable Mutex benchmark_mutex_;
|
||||
std::atomic<int> alive_threads_;
|
||||
Barrier start_stop_barrier_;
|
||||
Mutex end_cond_mutex_;
|
||||
Condition end_condition_;
|
||||
};
|
||||
|
||||
// Timer management class
|
||||
class ThreadTimer {
|
||||
public:
|
||||
ThreadTimer() = default;
|
||||
|
||||
// Called by each thread
|
||||
void StartTimer() {
|
||||
running_ = true;
|
||||
start_real_time_ = ChronoClockNow();
|
||||
start_cpu_time_ = ThreadCPUUsage();
|
||||
}
|
||||
|
||||
// Called by each thread
|
||||
void StopTimer() {
|
||||
CHECK(running_);
|
||||
running_ = false;
|
||||
real_time_used_ += ChronoClockNow() - start_real_time_;
|
||||
// Floating point error can result in the subtraction producing a negative
|
||||
// time. Guard against that.
|
||||
cpu_time_used_ += std::max<double>(ThreadCPUUsage() - start_cpu_time_, 0);
|
||||
}
|
||||
|
||||
// Called by each thread
|
||||
void SetIterationTime(double seconds) { manual_time_used_ += seconds; }
|
||||
|
||||
bool running() const { return running_; }
|
||||
|
||||
// REQUIRES: timer is not running
|
||||
double real_time_used() {
|
||||
CHECK(!running_);
|
||||
return real_time_used_;
|
||||
}
|
||||
|
||||
// REQUIRES: timer is not running
|
||||
double cpu_time_used() {
|
||||
CHECK(!running_);
|
||||
return cpu_time_used_;
|
||||
}
|
||||
|
||||
// REQUIRES: timer is not running
|
||||
double manual_time_used() {
|
||||
CHECK(!running_);
|
||||
return manual_time_used_;
|
||||
}
|
||||
|
||||
private:
|
||||
bool running_ = false; // Is the timer running
|
||||
double start_real_time_ = 0; // If running_
|
||||
double start_cpu_time_ = 0; // If running_
|
||||
|
||||
// Accumulated time so far (does not contain current slice if running_)
|
||||
double real_time_used_ = 0;
|
||||
double cpu_time_used_ = 0;
|
||||
// Manually set iteration time. User sets this with SetIterationTime(seconds).
|
||||
double manual_time_used_ = 0;
|
||||
};
|
||||
|
||||
namespace {
|
||||
|
||||
BenchmarkReporter::Run CreateRunReport(
|
||||
const benchmark::internal::Benchmark::Instance& b,
|
||||
const internal::ThreadManager::Result& results, size_t iters,
|
||||
const internal::ThreadManager::Result& results,
|
||||
double seconds) {
|
||||
// Create report about this benchmark run.
|
||||
BenchmarkReporter::Run report;
|
||||
|
|
@ -228,8 +124,8 @@ BenchmarkReporter::Run CreateRunReport(
|
|||
report.error_occurred = results.has_error_;
|
||||
report.error_message = results.error_message_;
|
||||
report.report_label = results.report_label_;
|
||||
// Report the total iterations across all threads.
|
||||
report.iterations = static_cast<int64_t>(iters) * b.threads;
|
||||
// This is the total iterations across all threads.
|
||||
report.iterations = results.iterations;
|
||||
report.time_unit = b.time_unit;
|
||||
|
||||
if (!report.error_occurred) {
|
||||
|
|
@ -268,11 +164,12 @@ void RunInThread(const benchmark::internal::Benchmark::Instance* b,
|
|||
internal::ThreadTimer timer;
|
||||
State st(iters, b->arg, thread_id, b->threads, &timer, manager);
|
||||
b->benchmark->Run(st);
|
||||
CHECK(st.iterations() == st.max_iterations)
|
||||
CHECK(st.iterations() >= st.max_iterations)
|
||||
<< "Benchmark returned before State::KeepRunning() returned false!";
|
||||
{
|
||||
MutexLock l(manager->GetBenchmarkMutex());
|
||||
internal::ThreadManager::Result& results = manager->results;
|
||||
results.iterations += st.iterations();
|
||||
results.cpu_time_used += timer.cpu_time_used();
|
||||
results.real_time_used += timer.real_time_used();
|
||||
results.manual_time_used += timer.manual_time_used();
|
||||
|
|
@ -340,18 +237,17 @@ std::vector<BenchmarkReporter::Run> RunBenchmark(
|
|||
// Determine if this run should be reported; Either it has
|
||||
// run for a sufficient amount of time or because an error was reported.
|
||||
const bool should_report = repetition_num > 0
|
||||
|| has_explicit_iteration_count // An exact iteration count was requested
|
||||
|| has_explicit_iteration_count // An exact iteration count was requested
|
||||
|| results.has_error_
|
||||
|| iters >= kMaxIterations
|
||||
|| seconds >= min_time // the elapsed time is large enough
|
||||
|| iters >= kMaxIterations // No chance to try again, we hit the limit.
|
||||
|| seconds >= min_time // the elapsed time is large enough
|
||||
// CPU time is specified but the elapsed real time greatly exceeds the
|
||||
// minimum time. Note that user provided timers are except from this
|
||||
// sanity check.
|
||||
|| ((results.real_time_used >= 5 * min_time) && !b.use_manual_time);
|
||||
|
||||
if (should_report) {
|
||||
BenchmarkReporter::Run report =
|
||||
CreateRunReport(b, results, iters, seconds);
|
||||
BenchmarkReporter::Run report = CreateRunReport(b, results, seconds);
|
||||
if (!report.error_occurred && b.complexity != oNone)
|
||||
complexity_reports->push_back(report);
|
||||
reports.push_back(report);
|
||||
|
|
@ -394,26 +290,44 @@ std::vector<BenchmarkReporter::Run> RunBenchmark(
|
|||
} // namespace
|
||||
} // namespace internal
|
||||
|
||||
State::State(size_t max_iters, const std::vector<int>& ranges, int thread_i,
|
||||
State::State(size_t max_iters, const std::vector<int64_t>& ranges, int thread_i,
|
||||
int n_threads, internal::ThreadTimer* timer,
|
||||
internal::ThreadManager* manager)
|
||||
: started_(false),
|
||||
: total_iterations_(0),
|
||||
batch_leftover_(0),
|
||||
max_iterations(max_iters),
|
||||
started_(false),
|
||||
finished_(false),
|
||||
total_iterations_(max_iters + 1),
|
||||
error_occurred_(false),
|
||||
range_(ranges),
|
||||
bytes_processed_(0),
|
||||
items_processed_(0),
|
||||
complexity_n_(0),
|
||||
error_occurred_(false),
|
||||
counters(),
|
||||
thread_index(thread_i),
|
||||
threads(n_threads),
|
||||
max_iterations(max_iters),
|
||||
timer_(timer),
|
||||
manager_(manager) {
|
||||
CHECK(max_iterations != 0) << "At least one iteration must be run";
|
||||
CHECK(total_iterations_ != 0) << "max iterations wrapped around";
|
||||
CHECK_LT(thread_index, threads) << "thread_index must be less than threads";
|
||||
|
||||
// Note: The use of offsetof below is technically undefined until C++17
|
||||
// because State is not a standard layout type. However, all compilers
|
||||
// currently provide well-defined behavior as an extension (which is
|
||||
// demonstrated since constexpr evaluation must diagnose all undefined
|
||||
// behavior). However, GCC and Clang also warn about this use of offsetof,
|
||||
// which must be suppressed.
|
||||
#ifdef __GNUC__
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Winvalid-offsetof"
|
||||
#endif
|
||||
// Offset tests to ensure commonly accessed data is on the first cache line.
|
||||
const int cache_line_size = 64;
|
||||
static_assert(offsetof(State, error_occurred_) <=
|
||||
(cache_line_size - sizeof(error_occurred_)), "");
|
||||
#ifdef __GNUC__
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
}
|
||||
|
||||
void State::PauseTiming() {
|
||||
|
|
@ -437,7 +351,7 @@ void State::SkipWithError(const char* msg) {
|
|||
manager_->results.has_error_ = true;
|
||||
}
|
||||
}
|
||||
total_iterations_ = 1;
|
||||
total_iterations_ = 0;
|
||||
if (timer_->running()) timer_->StopTimer();
|
||||
}
|
||||
|
||||
|
|
@ -453,6 +367,7 @@ void State::SetLabel(const char* label) {
|
|||
void State::StartKeepRunning() {
|
||||
CHECK(!started_ && !finished_);
|
||||
started_ = true;
|
||||
total_iterations_ = error_occurred_ ? 0 : max_iterations;
|
||||
manager_->StartStopBarrier();
|
||||
if (!error_occurred_) ResumeTiming();
|
||||
}
|
||||
|
|
@ -462,8 +377,8 @@ void State::FinishKeepRunning() {
|
|||
if (!error_occurred_) {
|
||||
PauseTiming();
|
||||
}
|
||||
// Total iterations has now wrapped around zero. Fix this.
|
||||
total_iterations_ = 1;
|
||||
// Total iterations has now wrapped around past 0. Fix this.
|
||||
total_iterations_ = 0;
|
||||
finished_ = true;
|
||||
manager_->StartStopBarrier();
|
||||
}
|
||||
|
|
@ -495,7 +410,7 @@ void RunBenchmarks(const std::vector<Benchmark::Instance>& benchmarks,
|
|||
BenchmarkReporter::Context context;
|
||||
context.name_field_width = name_field_width;
|
||||
|
||||
// Keep track of runing times of all instances of current benchmark
|
||||
// Keep track of running times of all instances of current benchmark
|
||||
std::vector<BenchmarkReporter::Run> complexity_reports;
|
||||
|
||||
// We flush streams after invoking reporter methods that write to them. This
|
||||
|
|
@ -653,6 +568,7 @@ void PrintUsageAndExit() {
|
|||
|
||||
void ParseCommandLineFlags(int* argc, char** argv) {
|
||||
using namespace benchmark;
|
||||
BenchmarkReporter::Context::executable_name = argv[0];
|
||||
for (int i = 1; i < *argc; ++i) {
|
||||
if (ParseBoolFlag(argv[i], "benchmark_list_tests",
|
||||
&FLAGS_benchmark_list_tests) ||
|
||||
|
|
|
|||
2
benchmarks/thirdparty/benchmark/src/benchmark_api_internal.h
vendored
Normal file → Executable file
2
benchmarks/thirdparty/benchmark/src/benchmark_api_internal.h
vendored
Normal file → Executable file
|
|
@ -17,7 +17,7 @@ struct Benchmark::Instance {
|
|||
std::string name;
|
||||
Benchmark* benchmark;
|
||||
ReportMode report_mode;
|
||||
std::vector<int> arg;
|
||||
std::vector<int64_t> arg;
|
||||
TimeUnit time_unit;
|
||||
int range_multiplier;
|
||||
bool use_real_time;
|
||||
|
|
|
|||
17
benchmarks/thirdparty/benchmark/src/benchmark_main.cc
vendored
Executable file
17
benchmarks/thirdparty/benchmark/src/benchmark_main.cc
vendored
Executable file
|
|
@ -0,0 +1,17 @@
|
|||
// Copyright 2018 Google Inc. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "benchmark/benchmark.h"
|
||||
|
||||
BENCHMARK_MAIN();
|
||||
83
benchmarks/thirdparty/benchmark/src/benchmark_register.cc
vendored
Normal file → Executable file
83
benchmarks/thirdparty/benchmark/src/benchmark_register.cc
vendored
Normal file → Executable file
|
|
@ -12,12 +12,12 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "benchmark/benchmark.h"
|
||||
#include "benchmark_api_internal.h"
|
||||
#include "internal_macros.h"
|
||||
#include "benchmark_register.h"
|
||||
|
||||
#ifndef BENCHMARK_OS_WINDOWS
|
||||
#ifndef BENCHMARK_OS_FUCHSIA
|
||||
#include <sys/resource.h>
|
||||
#endif
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
|
@ -34,13 +34,16 @@
|
|||
#include <sstream>
|
||||
#include <thread>
|
||||
|
||||
#include "benchmark/benchmark.h"
|
||||
#include "benchmark_api_internal.h"
|
||||
#include "check.h"
|
||||
#include "commandlineflags.h"
|
||||
#include "complexity.h"
|
||||
#include "statistics.h"
|
||||
#include "internal_macros.h"
|
||||
#include "log.h"
|
||||
#include "mutex.h"
|
||||
#include "re.h"
|
||||
#include "statistics.h"
|
||||
#include "string_util.h"
|
||||
#include "timers.h"
|
||||
|
||||
|
|
@ -74,7 +77,7 @@ class BenchmarkFamilies {
|
|||
|
||||
// Extract the list of benchmark instances that match the specified
|
||||
// regular expression.
|
||||
bool FindBenchmarks(const std::string& re,
|
||||
bool FindBenchmarks(std::string re,
|
||||
std::vector<Benchmark::Instance>* benchmarks,
|
||||
std::ostream* Err);
|
||||
|
||||
|
|
@ -104,13 +107,18 @@ void BenchmarkFamilies::ClearBenchmarks() {
|
|||
}
|
||||
|
||||
bool BenchmarkFamilies::FindBenchmarks(
|
||||
const std::string& spec, std::vector<Benchmark::Instance>* benchmarks,
|
||||
std::string spec, std::vector<Benchmark::Instance>* benchmarks,
|
||||
std::ostream* ErrStream) {
|
||||
CHECK(ErrStream);
|
||||
auto& Err = *ErrStream;
|
||||
// Make regular expression out of command-line flag
|
||||
std::string error_msg;
|
||||
Regex re;
|
||||
bool isNegativeFilter = false;
|
||||
if(spec[0] == '-') {
|
||||
spec.replace(0, 1, "");
|
||||
isNegativeFilter = true;
|
||||
}
|
||||
if (!re.Init(spec, &error_msg)) {
|
||||
Err << "Could not compile benchmark re: " << error_msg << std::endl;
|
||||
return false;
|
||||
|
|
@ -170,20 +178,20 @@ bool BenchmarkFamilies::FindBenchmarks(
|
|||
const auto& arg_name = family->arg_names_[arg_i];
|
||||
if (!arg_name.empty()) {
|
||||
instance.name +=
|
||||
StringPrintF("%s:", family->arg_names_[arg_i].c_str());
|
||||
StrFormat("%s:", family->arg_names_[arg_i].c_str());
|
||||
}
|
||||
}
|
||||
|
||||
instance.name += StringPrintF("%d", arg);
|
||||
|
||||
instance.name += StrFormat("%d", arg);
|
||||
++arg_i;
|
||||
}
|
||||
|
||||
if (!IsZero(family->min_time_))
|
||||
instance.name += StringPrintF("/min_time:%0.3f", family->min_time_);
|
||||
instance.name += StrFormat("/min_time:%0.3f", family->min_time_);
|
||||
if (family->iterations_ != 0)
|
||||
instance.name += StringPrintF("/iterations:%d", family->iterations_);
|
||||
instance.name += StrFormat("/iterations:%d", family->iterations_);
|
||||
if (family->repetitions_ != 0)
|
||||
instance.name += StringPrintF("/repeats:%d", family->repetitions_);
|
||||
instance.name += StrFormat("/repeats:%d", family->repetitions_);
|
||||
|
||||
if (family->use_manual_time_) {
|
||||
instance.name += "/manual_time";
|
||||
|
|
@ -193,10 +201,11 @@ bool BenchmarkFamilies::FindBenchmarks(
|
|||
|
||||
// Add the number of threads used to the name
|
||||
if (!family->thread_counts_.empty()) {
|
||||
instance.name += StringPrintF("/threads:%d", instance.threads);
|
||||
instance.name += StrFormat("/threads:%d", instance.threads);
|
||||
}
|
||||
|
||||
if (re.Match(instance.name)) {
|
||||
if ((re.Match(instance.name) && !isNegativeFilter) ||
|
||||
(!re.Match(instance.name) && isNegativeFilter)) {
|
||||
instance.last_benchmark_instance = (&args == &family->args_.back());
|
||||
benchmarks->push_back(std::move(instance));
|
||||
}
|
||||
|
|
@ -244,30 +253,7 @@ Benchmark::Benchmark(const char* name)
|
|||
|
||||
Benchmark::~Benchmark() {}
|
||||
|
||||
void Benchmark::AddRange(std::vector<int>* dst, int lo, int hi, int mult) {
|
||||
CHECK_GE(lo, 0);
|
||||
CHECK_GE(hi, lo);
|
||||
CHECK_GE(mult, 2);
|
||||
|
||||
// Add "lo"
|
||||
dst->push_back(lo);
|
||||
|
||||
static const int kint32max = std::numeric_limits<int32_t>::max();
|
||||
|
||||
// Now space out the benchmarks in multiples of "mult"
|
||||
for (int32_t i = 1; i < kint32max / mult; i *= mult) {
|
||||
if (i >= hi) break;
|
||||
if (i > lo) {
|
||||
dst->push_back(i);
|
||||
}
|
||||
}
|
||||
// Add "hi" (if different from "lo")
|
||||
if (hi != lo) {
|
||||
dst->push_back(hi);
|
||||
}
|
||||
}
|
||||
|
||||
Benchmark* Benchmark::Arg(int x) {
|
||||
Benchmark* Benchmark::Arg(int64_t x) {
|
||||
CHECK(ArgsCnt() == -1 || ArgsCnt() == 1);
|
||||
args_.push_back({x});
|
||||
return this;
|
||||
|
|
@ -278,20 +264,21 @@ Benchmark* Benchmark::Unit(TimeUnit unit) {
|
|||
return this;
|
||||
}
|
||||
|
||||
Benchmark* Benchmark::Range(int start, int limit) {
|
||||
Benchmark* Benchmark::Range(int64_t start, int64_t limit) {
|
||||
CHECK(ArgsCnt() == -1 || ArgsCnt() == 1);
|
||||
std::vector<int> arglist;
|
||||
std::vector<int64_t> arglist;
|
||||
AddRange(&arglist, start, limit, range_multiplier_);
|
||||
|
||||
for (int i : arglist) {
|
||||
for (int64_t i : arglist) {
|
||||
args_.push_back({i});
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
Benchmark* Benchmark::Ranges(const std::vector<std::pair<int, int>>& ranges) {
|
||||
Benchmark* Benchmark::Ranges(
|
||||
const std::vector<std::pair<int64_t, int64_t>>& ranges) {
|
||||
CHECK(ArgsCnt() == -1 || ArgsCnt() == static_cast<int>(ranges.size()));
|
||||
std::vector<std::vector<int>> arglists(ranges.size());
|
||||
std::vector<std::vector<int64_t>> arglists(ranges.size());
|
||||
std::size_t total = 1;
|
||||
for (std::size_t i = 0; i < ranges.size(); i++) {
|
||||
AddRange(&arglists[i], ranges[i].first, ranges[i].second,
|
||||
|
|
@ -302,7 +289,7 @@ Benchmark* Benchmark::Ranges(const std::vector<std::pair<int, int>>& ranges) {
|
|||
std::vector<std::size_t> ctr(arglists.size(), 0);
|
||||
|
||||
for (std::size_t i = 0; i < total; i++) {
|
||||
std::vector<int> tmp;
|
||||
std::vector<int64_t> tmp;
|
||||
tmp.reserve(arglists.size());
|
||||
|
||||
for (std::size_t j = 0; j < arglists.size(); j++) {
|
||||
|
|
@ -334,17 +321,17 @@ Benchmark* Benchmark::ArgNames(const std::vector<std::string>& names) {
|
|||
return this;
|
||||
}
|
||||
|
||||
Benchmark* Benchmark::DenseRange(int start, int limit, int step) {
|
||||
Benchmark* Benchmark::DenseRange(int64_t start, int64_t limit, int step) {
|
||||
CHECK(ArgsCnt() == -1 || ArgsCnt() == 1);
|
||||
CHECK_GE(start, 0);
|
||||
CHECK_LE(start, limit);
|
||||
for (int arg = start; arg <= limit; arg += step) {
|
||||
for (int64_t arg = start; arg <= limit; arg += step) {
|
||||
args_.push_back({arg});
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
Benchmark* Benchmark::Args(const std::vector<int>& args) {
|
||||
Benchmark* Benchmark::Args(const std::vector<int64_t>& args) {
|
||||
CHECK(ArgsCnt() == -1 || ArgsCnt() == static_cast<int>(args.size()));
|
||||
args_.push_back(args);
|
||||
return this;
|
||||
|
|
@ -361,7 +348,6 @@ Benchmark* Benchmark::RangeMultiplier(int multiplier) {
|
|||
return this;
|
||||
}
|
||||
|
||||
|
||||
Benchmark* Benchmark::MinTime(double t) {
|
||||
CHECK(t > 0.0);
|
||||
CHECK(iterations_ == 0);
|
||||
|
|
@ -369,7 +355,6 @@ Benchmark* Benchmark::MinTime(double t) {
|
|||
return this;
|
||||
}
|
||||
|
||||
|
||||
Benchmark* Benchmark::Iterations(size_t n) {
|
||||
CHECK(n > 0);
|
||||
CHECK(IsZero(min_time_));
|
||||
|
|
|
|||
33
benchmarks/thirdparty/benchmark/src/benchmark_register.h
vendored
Executable file
33
benchmarks/thirdparty/benchmark/src/benchmark_register.h
vendored
Executable file
|
|
@ -0,0 +1,33 @@
|
|||
#ifndef BENCHMARK_REGISTER_H
|
||||
#define BENCHMARK_REGISTER_H
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "check.h"
|
||||
|
||||
template <typename T>
|
||||
void AddRange(std::vector<T>* dst, T lo, T hi, int mult) {
|
||||
CHECK_GE(lo, 0);
|
||||
CHECK_GE(hi, lo);
|
||||
CHECK_GE(mult, 2);
|
||||
|
||||
// Add "lo"
|
||||
dst->push_back(lo);
|
||||
|
||||
static const T kmax = std::numeric_limits<T>::max();
|
||||
|
||||
// Now space out the benchmarks in multiples of "mult"
|
||||
for (T i = 1; i < kmax / mult; i *= mult) {
|
||||
if (i >= hi) break;
|
||||
if (i > lo) {
|
||||
dst->push_back(i);
|
||||
}
|
||||
}
|
||||
|
||||
// Add "hi" (if different from "lo")
|
||||
if (hi != lo) {
|
||||
dst->push_back(hi);
|
||||
}
|
||||
}
|
||||
|
||||
#endif // BENCHMARK_REGISTER_H
|
||||
0
benchmarks/thirdparty/benchmark/src/check.h
vendored
Normal file → Executable file
0
benchmarks/thirdparty/benchmark/src/check.h
vendored
Normal file → Executable file
0
benchmarks/thirdparty/benchmark/src/colorprint.cc
vendored
Normal file → Executable file
0
benchmarks/thirdparty/benchmark/src/colorprint.cc
vendored
Normal file → Executable file
0
benchmarks/thirdparty/benchmark/src/colorprint.h
vendored
Normal file → Executable file
0
benchmarks/thirdparty/benchmark/src/colorprint.h
vendored
Normal file → Executable file
0
benchmarks/thirdparty/benchmark/src/commandlineflags.cc
vendored
Normal file → Executable file
0
benchmarks/thirdparty/benchmark/src/commandlineflags.cc
vendored
Normal file → Executable file
0
benchmarks/thirdparty/benchmark/src/commandlineflags.h
vendored
Normal file → Executable file
0
benchmarks/thirdparty/benchmark/src/commandlineflags.h
vendored
Normal file → Executable file
22
benchmarks/thirdparty/benchmark/src/complexity.cc
vendored
Normal file → Executable file
22
benchmarks/thirdparty/benchmark/src/complexity.cc
vendored
Normal file → Executable file
|
|
@ -28,18 +28,18 @@ namespace benchmark {
|
|||
BigOFunc* FittingCurve(BigO complexity) {
|
||||
switch (complexity) {
|
||||
case oN:
|
||||
return [](int n) -> double { return n; };
|
||||
return [](int64_t n) -> double { return static_cast<double>(n); };
|
||||
case oNSquared:
|
||||
return [](int n) -> double { return std::pow(n, 2); };
|
||||
return [](int64_t n) -> double { return std::pow(n, 2); };
|
||||
case oNCubed:
|
||||
return [](int n) -> double { return std::pow(n, 3); };
|
||||
return [](int64_t n) -> double { return std::pow(n, 3); };
|
||||
case oLogN:
|
||||
return [](int n) { return log2(n); };
|
||||
return [](int64_t n) { return log2(n); };
|
||||
case oNLogN:
|
||||
return [](int n) { return n * log2(n); };
|
||||
return [](int64_t n) { return n * log2(n); };
|
||||
case o1:
|
||||
default:
|
||||
return [](int) { return 1.0; };
|
||||
return [](int64_t) { return 1.0; };
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -65,15 +65,15 @@ std::string GetBigOString(BigO complexity) {
|
|||
|
||||
// Find the coefficient for the high-order term in the running time, by
|
||||
// minimizing the sum of squares of relative error, for the fitting curve
|
||||
// given by the lambda expresion.
|
||||
// given by the lambda expression.
|
||||
// - n : Vector containing the size of the benchmark tests.
|
||||
// - time : Vector containing the times for the benchmark tests.
|
||||
// - fitting_curve : lambda expresion (e.g. [](int n) {return n; };).
|
||||
// - fitting_curve : lambda expression (e.g. [](int64_t n) {return n; };).
|
||||
|
||||
// For a deeper explanation on the algorithm logic, look the README file at
|
||||
// http://github.com/ismaelJimenez/Minimal-Cpp-Least-Squared-Fit
|
||||
|
||||
LeastSq MinimalLeastSq(const std::vector<int>& n,
|
||||
LeastSq MinimalLeastSq(const std::vector<int64_t>& n,
|
||||
const std::vector<double>& time,
|
||||
BigOFunc* fitting_curve) {
|
||||
double sigma_gn = 0.0;
|
||||
|
|
@ -117,7 +117,7 @@ LeastSq MinimalLeastSq(const std::vector<int>& n,
|
|||
// - complexity : If different than oAuto, the fitting curve will stick to
|
||||
// this one. If it is oAuto, it will be calculated the best
|
||||
// fitting curve.
|
||||
LeastSq MinimalLeastSq(const std::vector<int>& n,
|
||||
LeastSq MinimalLeastSq(const std::vector<int64_t>& n,
|
||||
const std::vector<double>& time, const BigO complexity) {
|
||||
CHECK_EQ(n.size(), time.size());
|
||||
CHECK_GE(n.size(), 2); // Do not compute fitting curve is less than two
|
||||
|
|
@ -157,7 +157,7 @@ std::vector<BenchmarkReporter::Run> ComputeBigO(
|
|||
if (reports.size() < 2) return results;
|
||||
|
||||
// Accumulators.
|
||||
std::vector<int> n;
|
||||
std::vector<int64_t> n;
|
||||
std::vector<double> real_time;
|
||||
std::vector<double> cpu_time;
|
||||
|
||||
|
|
|
|||
0
benchmarks/thirdparty/benchmark/src/complexity.h
vendored
Normal file → Executable file
0
benchmarks/thirdparty/benchmark/src/complexity.h
vendored
Normal file → Executable file
0
benchmarks/thirdparty/benchmark/src/console_reporter.cc
vendored
Normal file → Executable file
0
benchmarks/thirdparty/benchmark/src/console_reporter.cc
vendored
Normal file → Executable file
0
benchmarks/thirdparty/benchmark/src/counter.cc
vendored
Normal file → Executable file
0
benchmarks/thirdparty/benchmark/src/counter.cc
vendored
Normal file → Executable file
0
benchmarks/thirdparty/benchmark/src/counter.h
vendored
Normal file → Executable file
0
benchmarks/thirdparty/benchmark/src/counter.h
vendored
Normal file → Executable file
0
benchmarks/thirdparty/benchmark/src/csv_reporter.cc
vendored
Normal file → Executable file
0
benchmarks/thirdparty/benchmark/src/csv_reporter.cc
vendored
Normal file → Executable file
5
benchmarks/thirdparty/benchmark/src/cycleclock.h
vendored
Normal file → Executable file
5
benchmarks/thirdparty/benchmark/src/cycleclock.h
vendored
Normal file → Executable file
|
|
@ -159,6 +159,11 @@ inline BENCHMARK_ALWAYS_INLINE int64_t Now() {
|
|||
struct timeval tv;
|
||||
gettimeofday(&tv, nullptr);
|
||||
return static_cast<int64_t>(tv.tv_sec) * 1000000 + tv.tv_usec;
|
||||
#elif defined(__s390__) // Covers both s390 and s390x.
|
||||
// Return the CPU clock.
|
||||
uint64_t tsc;
|
||||
asm("stck %0" : "=Q" (tsc) : : "cc");
|
||||
return tsc;
|
||||
#else
|
||||
// The soft failover to a generic implementation is automatic only for ARM.
|
||||
// For other platforms the developer is expected to make an attempt to create
|
||||
|
|
|
|||
9
benchmarks/thirdparty/benchmark/src/internal_macros.h
vendored
Normal file → Executable file
9
benchmarks/thirdparty/benchmark/src/internal_macros.h
vendored
Normal file → Executable file
|
|
@ -39,6 +39,7 @@
|
|||
#elif defined(_WIN32)
|
||||
#define BENCHMARK_OS_WINDOWS 1
|
||||
#elif defined(__APPLE__)
|
||||
#define BENCHMARK_OS_APPLE 1
|
||||
#include "TargetConditionals.h"
|
||||
#if defined(TARGET_OS_MAC)
|
||||
#define BENCHMARK_OS_MACOSX 1
|
||||
|
|
@ -50,14 +51,20 @@
|
|||
#define BENCHMARK_OS_FREEBSD 1
|
||||
#elif defined(__NetBSD__)
|
||||
#define BENCHMARK_OS_NETBSD 1
|
||||
#elif defined(__OpenBSD__)
|
||||
#define BENCHMARK_OS_OPENBSD 1
|
||||
#elif defined(__linux__)
|
||||
#define BENCHMARK_OS_LINUX 1
|
||||
#elif defined(__native_client__)
|
||||
#define BENCHMARK_OS_NACL 1
|
||||
#elif defined(EMSCRIPTEN)
|
||||
#elif defined(__EMSCRIPTEN__)
|
||||
#define BENCHMARK_OS_EMSCRIPTEN 1
|
||||
#elif defined(__rtems__)
|
||||
#define BENCHMARK_OS_RTEMS 1
|
||||
#elif defined(__Fuchsia__)
|
||||
#define BENCHMARK_OS_FUCHSIA 1
|
||||
#elif defined (__SVR4) && defined (__sun)
|
||||
#define BENCHMARK_OS_SOLARIS 1
|
||||
#endif
|
||||
|
||||
#if !__has_feature(cxx_exceptions) && !defined(__cpp_exceptions) \
|
||||
|
|
|
|||
10
benchmarks/thirdparty/benchmark/src/json_reporter.cc
vendored
Normal file → Executable file
10
benchmarks/thirdparty/benchmark/src/json_reporter.cc
vendored
Normal file → Executable file
|
|
@ -32,15 +32,15 @@ namespace benchmark {
|
|||
namespace {
|
||||
|
||||
std::string FormatKV(std::string const& key, std::string const& value) {
|
||||
return StringPrintF("\"%s\": \"%s\"", key.c_str(), value.c_str());
|
||||
return StrFormat("\"%s\": \"%s\"", key.c_str(), value.c_str());
|
||||
}
|
||||
|
||||
std::string FormatKV(std::string const& key, const char* value) {
|
||||
return StringPrintF("\"%s\": \"%s\"", key.c_str(), value);
|
||||
return StrFormat("\"%s\": \"%s\"", key.c_str(), value);
|
||||
}
|
||||
|
||||
std::string FormatKV(std::string const& key, bool value) {
|
||||
return StringPrintF("\"%s\": %s", key.c_str(), value ? "true" : "false");
|
||||
return StrFormat("\"%s\": %s", key.c_str(), value ? "true" : "false");
|
||||
}
|
||||
|
||||
std::string FormatKV(std::string const& key, int64_t value) {
|
||||
|
|
@ -77,6 +77,10 @@ bool JSONReporter::ReportContext(const Context& context) {
|
|||
std::string walltime_value = LocalDateTimeString();
|
||||
out << indent << FormatKV("date", walltime_value) << ",\n";
|
||||
|
||||
if (Context::executable_name) {
|
||||
out << indent << FormatKV("executable", Context::executable_name) << ",\n";
|
||||
}
|
||||
|
||||
CPUInfo const& info = context.cpu_info;
|
||||
out << indent << FormatKV("num_cpus", static_cast<int64_t>(info.num_cpus))
|
||||
<< ",\n";
|
||||
|
|
|
|||
0
benchmarks/thirdparty/benchmark/src/log.h
vendored
Normal file → Executable file
0
benchmarks/thirdparty/benchmark/src/log.h
vendored
Normal file → Executable file
0
benchmarks/thirdparty/benchmark/src/mutex.h
vendored
Normal file → Executable file
0
benchmarks/thirdparty/benchmark/src/mutex.h
vendored
Normal file → Executable file
24
benchmarks/thirdparty/benchmark/src/re.h
vendored
Normal file → Executable file
24
benchmarks/thirdparty/benchmark/src/re.h
vendored
Normal file → Executable file
|
|
@ -17,19 +17,31 @@
|
|||
|
||||
#include "internal_macros.h"
|
||||
|
||||
#if !defined(HAVE_STD_REGEX) && \
|
||||
!defined(HAVE_GNU_POSIX_REGEX) && \
|
||||
!defined(HAVE_POSIX_REGEX)
|
||||
// No explicit regex selection; detect based on builtin hints.
|
||||
#if defined(BENCHMARK_OS_LINUX) || defined(BENCHMARK_OS_APPLE)
|
||||
#define HAVE_POSIX_REGEX 1
|
||||
#elif __cplusplus >= 199711L
|
||||
#define HAVE_STD_REGEX 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Prefer C regex libraries when compiling w/o exceptions so that we can
|
||||
// correctly report errors.
|
||||
#if defined(BENCHMARK_HAS_NO_EXCEPTIONS) && defined(HAVE_STD_REGEX) && \
|
||||
#if defined(BENCHMARK_HAS_NO_EXCEPTIONS) && \
|
||||
defined(BENCHMARK_HAVE_STD_REGEX) && \
|
||||
(defined(HAVE_GNU_POSIX_REGEX) || defined(HAVE_POSIX_REGEX))
|
||||
#undef HAVE_STD_REGEX
|
||||
#undef HAVE_STD_REGEX
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_STD_REGEX)
|
||||
#include <regex>
|
||||
#include <regex>
|
||||
#elif defined(HAVE_GNU_POSIX_REGEX)
|
||||
#include <gnuregex.h>
|
||||
#include <gnuregex.h>
|
||||
#elif defined(HAVE_POSIX_REGEX)
|
||||
#include <regex.h>
|
||||
#include <regex.h>
|
||||
#else
|
||||
#error No regular expression backend was found!
|
||||
#endif
|
||||
|
|
@ -64,7 +76,7 @@ class Regex {
|
|||
#elif defined(HAVE_POSIX_REGEX) || defined(HAVE_GNU_POSIX_REGEX)
|
||||
regex_t re_;
|
||||
#else
|
||||
#error No regular expression backend implementation available
|
||||
#error No regular expression backend implementation available
|
||||
#endif
|
||||
};
|
||||
|
||||
|
|
|
|||
6
benchmarks/thirdparty/benchmark/src/reporter.cc
vendored
Normal file → Executable file
6
benchmarks/thirdparty/benchmark/src/reporter.cc
vendored
Normal file → Executable file
|
|
@ -37,6 +37,9 @@ void BenchmarkReporter::PrintBasicContext(std::ostream *out,
|
|||
|
||||
Out << LocalDateTimeString() << "\n";
|
||||
|
||||
if (context.executable_name)
|
||||
Out << "Running " << context.executable_name << "\n";
|
||||
|
||||
const CPUInfo &info = context.cpu_info;
|
||||
Out << "Run on (" << info.num_cpus << " X "
|
||||
<< (info.cycles_per_second / 1000000.0) << " MHz CPU "
|
||||
|
|
@ -64,6 +67,9 @@ void BenchmarkReporter::PrintBasicContext(std::ostream *out,
|
|||
#endif
|
||||
}
|
||||
|
||||
// No initializer because it's already initialized to NULL.
|
||||
const char* BenchmarkReporter::Context::executable_name;
|
||||
|
||||
BenchmarkReporter::Context::Context() : cpu_info(CPUInfo::Get()) {}
|
||||
|
||||
double BenchmarkReporter::Run::GetAdjustedRealTime() const {
|
||||
|
|
|
|||
0
benchmarks/thirdparty/benchmark/src/sleep.cc
vendored
Normal file → Executable file
0
benchmarks/thirdparty/benchmark/src/sleep.cc
vendored
Normal file → Executable file
0
benchmarks/thirdparty/benchmark/src/sleep.h
vendored
Normal file → Executable file
0
benchmarks/thirdparty/benchmark/src/sleep.h
vendored
Normal file → Executable file
25
benchmarks/thirdparty/benchmark/src/statistics.cc
vendored
Normal file → Executable file
25
benchmarks/thirdparty/benchmark/src/statistics.cc
vendored
Normal file → Executable file
|
|
@ -30,22 +30,25 @@ auto StatisticsSum = [](const std::vector<double>& v) {
|
|||
};
|
||||
|
||||
double StatisticsMean(const std::vector<double>& v) {
|
||||
if (v.size() == 0) return 0.0;
|
||||
if (v.empty()) return 0.0;
|
||||
return StatisticsSum(v) * (1.0 / v.size());
|
||||
}
|
||||
|
||||
double StatisticsMedian(const std::vector<double>& v) {
|
||||
if (v.size() < 3) return StatisticsMean(v);
|
||||
std::vector<double> partial;
|
||||
// we need roundDown(count/2)+1 slots
|
||||
partial.resize(1 + (v.size() / 2));
|
||||
std::partial_sort_copy(v.begin(), v.end(), partial.begin(), partial.end());
|
||||
// did we have odd number of samples?
|
||||
// if yes, then the last element of partially-sorted vector is the median
|
||||
// it no, then the average of the last two elements is the median
|
||||
std::vector<double> copy(v);
|
||||
|
||||
auto center = copy.begin() + v.size() / 2;
|
||||
std::nth_element(copy.begin(), center, copy.end());
|
||||
|
||||
// did we have an odd number of samples?
|
||||
// if yes, then center is the median
|
||||
// it no, then we are looking for the average between center and the value before
|
||||
if(v.size() % 2 == 1)
|
||||
return partial.back();
|
||||
return (partial[partial.size() - 2] + partial[partial.size() - 1]) / 2.0;
|
||||
return *center;
|
||||
auto center2 = copy.begin() + v.size() / 2 - 1;
|
||||
std::nth_element(copy.begin(), center2, copy.end());
|
||||
return (*center + *center2) / 2.0;
|
||||
}
|
||||
|
||||
// Return the sum of the squares of this sample set
|
||||
|
|
@ -62,7 +65,7 @@ auto Sqrt = [](const double dat) {
|
|||
|
||||
double StatisticsStdDev(const std::vector<double>& v) {
|
||||
const auto mean = StatisticsMean(v);
|
||||
if (v.size() == 0) return mean;
|
||||
if (v.empty()) return mean;
|
||||
|
||||
// Sample standard deviation is undefined for n = 1
|
||||
if (v.size() == 1)
|
||||
|
|
|
|||
0
benchmarks/thirdparty/benchmark/src/statistics.h
vendored
Normal file → Executable file
0
benchmarks/thirdparty/benchmark/src/statistics.h
vendored
Normal file → Executable file
6
benchmarks/thirdparty/benchmark/src/string_util.cc
vendored
Normal file → Executable file
6
benchmarks/thirdparty/benchmark/src/string_util.cc
vendored
Normal file → Executable file
|
|
@ -122,7 +122,7 @@ std::string HumanReadableNumber(double n, double one_k) {
|
|||
return ToBinaryStringFullySpecified(n, 1.1, 1, one_k);
|
||||
}
|
||||
|
||||
std::string StringPrintFImp(const char* msg, va_list args) {
|
||||
std::string StrFormatImp(const char* msg, va_list args) {
|
||||
// we might need a second shot at this, so pre-emptivly make a copy
|
||||
va_list args_cp;
|
||||
va_copy(args_cp, args);
|
||||
|
|
@ -152,10 +152,10 @@ std::string StringPrintFImp(const char* msg, va_list args) {
|
|||
return std::string(buff_ptr.get());
|
||||
}
|
||||
|
||||
std::string StringPrintF(const char* format, ...) {
|
||||
std::string StrFormat(const char* format, ...) {
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
std::string tmp = StringPrintFImp(format, args);
|
||||
std::string tmp = StrFormatImp(format, args);
|
||||
va_end(args);
|
||||
return tmp;
|
||||
}
|
||||
|
|
|
|||
10
benchmarks/thirdparty/benchmark/src/string_util.h
vendored
Normal file → Executable file
10
benchmarks/thirdparty/benchmark/src/string_util.h
vendored
Normal file → Executable file
|
|
@ -12,23 +12,23 @@ void AppendHumanReadable(int n, std::string* str);
|
|||
|
||||
std::string HumanReadableNumber(double n, double one_k = 1024.0);
|
||||
|
||||
std::string StringPrintF(const char* format, ...);
|
||||
std::string StrFormat(const char* format, ...);
|
||||
|
||||
inline std::ostream& StringCatImp(std::ostream& out) BENCHMARK_NOEXCEPT {
|
||||
inline std::ostream& StrCatImp(std::ostream& out) BENCHMARK_NOEXCEPT {
|
||||
return out;
|
||||
}
|
||||
|
||||
template <class First, class... Rest>
|
||||
inline std::ostream& StringCatImp(std::ostream& out, First&& f,
|
||||
inline std::ostream& StrCatImp(std::ostream& out, First&& f,
|
||||
Rest&&... rest) {
|
||||
out << std::forward<First>(f);
|
||||
return StringCatImp(out, std::forward<Rest>(rest)...);
|
||||
return StrCatImp(out, std::forward<Rest>(rest)...);
|
||||
}
|
||||
|
||||
template <class... Args>
|
||||
inline std::string StrCat(Args&&... args) {
|
||||
std::ostringstream ss;
|
||||
StringCatImp(ss, std::forward<Args>(args)...);
|
||||
StrCatImp(ss, std::forward<Args>(args)...);
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
|
|
|
|||
78
benchmarks/thirdparty/benchmark/src/sysinfo.cc
vendored
Normal file → Executable file
78
benchmarks/thirdparty/benchmark/src/sysinfo.cc
vendored
Normal file → Executable file
|
|
@ -16,20 +16,26 @@
|
|||
|
||||
#ifdef BENCHMARK_OS_WINDOWS
|
||||
#include <Shlwapi.h>
|
||||
#undef StrCat // Don't let StrCat in string_util.h be renamed to lstrcatA
|
||||
#include <VersionHelpers.h>
|
||||
#include <Windows.h>
|
||||
#else
|
||||
#include <fcntl.h>
|
||||
#ifndef BENCHMARK_OS_FUCHSIA
|
||||
#include <sys/resource.h>
|
||||
#endif
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h> // this header must be included before 'sys/sysctl.h' to avoid compilation error on FreeBSD
|
||||
#include <unistd.h>
|
||||
#if defined BENCHMARK_OS_FREEBSD || defined BENCHMARK_OS_MACOSX || \
|
||||
defined BENCHMARK_OS_NETBSD
|
||||
defined BENCHMARK_OS_NETBSD || defined BENCHMARK_OS_OPENBSD
|
||||
#define BENCHMARK_HAS_SYSCTL
|
||||
#include <sys/sysctl.h>
|
||||
#endif
|
||||
#endif
|
||||
#if defined(BENCHMARK_OS_SOLARIS)
|
||||
#include <kstat.h>
|
||||
#endif
|
||||
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
|
|
@ -130,6 +136,26 @@ struct ValueUnion {
|
|||
};
|
||||
|
||||
ValueUnion GetSysctlImp(std::string const& Name) {
|
||||
#if defined BENCHMARK_OS_OPENBSD
|
||||
int mib[2];
|
||||
|
||||
mib[0] = CTL_HW;
|
||||
if ((Name == "hw.ncpu") || (Name == "hw.cpuspeed")){
|
||||
ValueUnion buff(sizeof(int));
|
||||
|
||||
if (Name == "hw.ncpu") {
|
||||
mib[1] = HW_NCPU;
|
||||
} else {
|
||||
mib[1] = HW_CPUSPEED;
|
||||
}
|
||||
|
||||
if (sysctl(mib, 2, buff.data(), &buff.Size, nullptr, 0) == -1) {
|
||||
return ValueUnion();
|
||||
}
|
||||
return buff;
|
||||
}
|
||||
return ValueUnion();
|
||||
#else
|
||||
size_t CurBuffSize = 0;
|
||||
if (sysctlbyname(Name.c_str(), nullptr, &CurBuffSize, nullptr, 0) == -1)
|
||||
return ValueUnion();
|
||||
|
|
@ -138,6 +164,7 @@ ValueUnion GetSysctlImp(std::string const& Name) {
|
|||
if (sysctlbyname(Name.c_str(), buff.data(), &buff.Size, nullptr, 0) == 0)
|
||||
return buff;
|
||||
return ValueUnion();
|
||||
#endif
|
||||
}
|
||||
|
||||
BENCHMARK_MAYBE_UNUSED
|
||||
|
|
@ -303,7 +330,7 @@ std::vector<CPUInfo::CacheInfo> GetCacheSizesWindows() {
|
|||
if (!B.test(0)) continue;
|
||||
CInfo* Cache = &it->Cache;
|
||||
CPUInfo::CacheInfo C;
|
||||
C.num_sharing = B.count();
|
||||
C.num_sharing = static_cast<int>(B.count());
|
||||
C.level = Cache->Level;
|
||||
C.size = Cache->Size;
|
||||
switch (Cache->Type) {
|
||||
|
|
@ -354,6 +381,15 @@ int GetNumCPUs() {
|
|||
return sysinfo.dwNumberOfProcessors; // number of logical
|
||||
// processors in the current
|
||||
// group
|
||||
#elif defined(BENCHMARK_OS_SOLARIS)
|
||||
// Returns -1 in case of a failure.
|
||||
int NumCPU = sysconf(_SC_NPROCESSORS_ONLN);
|
||||
if (NumCPU < 0) {
|
||||
fprintf(stderr,
|
||||
"sysconf(_SC_NPROCESSORS_ONLN) failed with error: %s\n",
|
||||
strerror(errno));
|
||||
}
|
||||
return NumCPU;
|
||||
#else
|
||||
int NumCPUs = 0;
|
||||
int MaxID = -1;
|
||||
|
|
@ -441,7 +477,7 @@ double GetCPUCyclesPerSecond() {
|
|||
std::string value;
|
||||
if (SplitIdx != std::string::npos) value = ln.substr(SplitIdx + 1);
|
||||
// When parsing the "cpu MHz" and "bogomips" (fallback) entries, we only
|
||||
// accept postive values. Some environments (virtual machines) report zero,
|
||||
// accept positive values. Some environments (virtual machines) report zero,
|
||||
// which would cause infinite looping in WallTime_Init.
|
||||
if (startsWithKey(ln, "cpu MHz")) {
|
||||
if (!value.empty()) {
|
||||
|
|
@ -473,12 +509,17 @@ double GetCPUCyclesPerSecond() {
|
|||
constexpr auto* FreqStr =
|
||||
#if defined(BENCHMARK_OS_FREEBSD) || defined(BENCHMARK_OS_NETBSD)
|
||||
"machdep.tsc_freq";
|
||||
#elif defined BENCHMARK_OS_OPENBSD
|
||||
"hw.cpuspeed";
|
||||
#else
|
||||
"hw.cpufrequency";
|
||||
#endif
|
||||
unsigned long long hz = 0;
|
||||
#if defined BENCHMARK_OS_OPENBSD
|
||||
if (GetSysctl(FreqStr, &hz)) return hz * 1000000;
|
||||
#else
|
||||
if (GetSysctl(FreqStr, &hz)) return hz;
|
||||
|
||||
#endif
|
||||
fprintf(stderr, "Unable to determine clock rate from sysctl: %s: %s\n",
|
||||
FreqStr, strerror(errno));
|
||||
|
||||
|
|
@ -493,6 +534,35 @@ double GetCPUCyclesPerSecond() {
|
|||
"~MHz", nullptr, &data, &data_size)))
|
||||
return static_cast<double>((int64_t)data *
|
||||
(int64_t)(1000 * 1000)); // was mhz
|
||||
#elif defined (BENCHMARK_OS_SOLARIS)
|
||||
kstat_ctl_t *kc = kstat_open();
|
||||
if (!kc) {
|
||||
std::cerr << "failed to open /dev/kstat\n";
|
||||
return -1;
|
||||
}
|
||||
kstat_t *ksp = kstat_lookup(kc, (char*)"cpu_info", -1, (char*)"cpu_info0");
|
||||
if (!ksp) {
|
||||
std::cerr << "failed to lookup in /dev/kstat\n";
|
||||
return -1;
|
||||
}
|
||||
if (kstat_read(kc, ksp, NULL) < 0) {
|
||||
std::cerr << "failed to read from /dev/kstat\n";
|
||||
return -1;
|
||||
}
|
||||
kstat_named_t *knp =
|
||||
(kstat_named_t*)kstat_data_lookup(ksp, (char*)"current_clock_Hz");
|
||||
if (!knp) {
|
||||
std::cerr << "failed to lookup data in /dev/kstat\n";
|
||||
return -1;
|
||||
}
|
||||
if (knp->data_type != KSTAT_DATA_UINT64) {
|
||||
std::cerr << "current_clock_Hz is of unexpected data type: "
|
||||
<< knp->data_type << "\n";
|
||||
return -1;
|
||||
}
|
||||
double clock_hz = knp->value.ui64;
|
||||
kstat_close(kc);
|
||||
return clock_hz;
|
||||
#endif
|
||||
// If we've fallen through, attempt to roughly estimate the CPU clock rate.
|
||||
const int estimate_time_ms = 1000;
|
||||
|
|
|
|||
66
benchmarks/thirdparty/benchmark/src/thread_manager.h
vendored
Executable file
66
benchmarks/thirdparty/benchmark/src/thread_manager.h
vendored
Executable file
|
|
@ -0,0 +1,66 @@
|
|||
#ifndef BENCHMARK_THREAD_MANAGER_H
|
||||
#define BENCHMARK_THREAD_MANAGER_H
|
||||
|
||||
#include <atomic>
|
||||
|
||||
#include "benchmark/benchmark.h"
|
||||
#include "mutex.h"
|
||||
|
||||
namespace benchmark {
|
||||
namespace internal {
|
||||
|
||||
class ThreadManager {
|
||||
public:
|
||||
ThreadManager(int num_threads)
|
||||
: alive_threads_(num_threads), start_stop_barrier_(num_threads) {}
|
||||
|
||||
Mutex& GetBenchmarkMutex() const RETURN_CAPABILITY(benchmark_mutex_) {
|
||||
return benchmark_mutex_;
|
||||
}
|
||||
|
||||
bool StartStopBarrier() EXCLUDES(end_cond_mutex_) {
|
||||
return start_stop_barrier_.wait();
|
||||
}
|
||||
|
||||
void NotifyThreadComplete() EXCLUDES(end_cond_mutex_) {
|
||||
start_stop_barrier_.removeThread();
|
||||
if (--alive_threads_ == 0) {
|
||||
MutexLock lock(end_cond_mutex_);
|
||||
end_condition_.notify_all();
|
||||
}
|
||||
}
|
||||
|
||||
void WaitForAllThreads() EXCLUDES(end_cond_mutex_) {
|
||||
MutexLock lock(end_cond_mutex_);
|
||||
end_condition_.wait(lock.native_handle(),
|
||||
[this]() { return alive_threads_ == 0; });
|
||||
}
|
||||
|
||||
public:
|
||||
struct Result {
|
||||
int64_t iterations = 0;
|
||||
double real_time_used = 0;
|
||||
double cpu_time_used = 0;
|
||||
double manual_time_used = 0;
|
||||
int64_t bytes_processed = 0;
|
||||
int64_t items_processed = 0;
|
||||
int64_t complexity_n = 0;
|
||||
std::string report_label_;
|
||||
std::string error_message_;
|
||||
bool has_error_ = false;
|
||||
UserCounters counters;
|
||||
};
|
||||
GUARDED_BY(GetBenchmarkMutex()) Result results;
|
||||
|
||||
private:
|
||||
mutable Mutex benchmark_mutex_;
|
||||
std::atomic<int> alive_threads_;
|
||||
Barrier start_stop_barrier_;
|
||||
Mutex end_cond_mutex_;
|
||||
Condition end_condition_;
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
} // namespace benchmark
|
||||
|
||||
#endif // BENCHMARK_THREAD_MANAGER_H
|
||||
69
benchmarks/thirdparty/benchmark/src/thread_timer.h
vendored
Executable file
69
benchmarks/thirdparty/benchmark/src/thread_timer.h
vendored
Executable file
|
|
@ -0,0 +1,69 @@
|
|||
#ifndef BENCHMARK_THREAD_TIMER_H
|
||||
#define BENCHMARK_THREAD_TIMER_H
|
||||
|
||||
#include "check.h"
|
||||
#include "timers.h"
|
||||
|
||||
namespace benchmark {
|
||||
namespace internal {
|
||||
|
||||
class ThreadTimer {
|
||||
public:
|
||||
ThreadTimer() = default;
|
||||
|
||||
// Called by each thread
|
||||
void StartTimer() {
|
||||
running_ = true;
|
||||
start_real_time_ = ChronoClockNow();
|
||||
start_cpu_time_ = ThreadCPUUsage();
|
||||
}
|
||||
|
||||
// Called by each thread
|
||||
void StopTimer() {
|
||||
CHECK(running_);
|
||||
running_ = false;
|
||||
real_time_used_ += ChronoClockNow() - start_real_time_;
|
||||
// Floating point error can result in the subtraction producing a negative
|
||||
// time. Guard against that.
|
||||
cpu_time_used_ += std::max<double>(ThreadCPUUsage() - start_cpu_time_, 0);
|
||||
}
|
||||
|
||||
// Called by each thread
|
||||
void SetIterationTime(double seconds) { manual_time_used_ += seconds; }
|
||||
|
||||
bool running() const { return running_; }
|
||||
|
||||
// REQUIRES: timer is not running
|
||||
double real_time_used() {
|
||||
CHECK(!running_);
|
||||
return real_time_used_;
|
||||
}
|
||||
|
||||
// REQUIRES: timer is not running
|
||||
double cpu_time_used() {
|
||||
CHECK(!running_);
|
||||
return cpu_time_used_;
|
||||
}
|
||||
|
||||
// REQUIRES: timer is not running
|
||||
double manual_time_used() {
|
||||
CHECK(!running_);
|
||||
return manual_time_used_;
|
||||
}
|
||||
|
||||
private:
|
||||
bool running_ = false; // Is the timer running
|
||||
double start_real_time_ = 0; // If running_
|
||||
double start_cpu_time_ = 0; // If running_
|
||||
|
||||
// Accumulated time so far (does not contain current slice if running_)
|
||||
double real_time_used_ = 0;
|
||||
double cpu_time_used_ = 0;
|
||||
// Manually set iteration time. User sets this with SetIterationTime(seconds).
|
||||
double manual_time_used_ = 0;
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
} // namespace benchmark
|
||||
|
||||
#endif // BENCHMARK_THREAD_TIMER_H
|
||||
11
benchmarks/thirdparty/benchmark/src/timers.cc
vendored
Normal file → Executable file
11
benchmarks/thirdparty/benchmark/src/timers.cc
vendored
Normal file → Executable file
|
|
@ -17,11 +17,14 @@
|
|||
|
||||
#ifdef BENCHMARK_OS_WINDOWS
|
||||
#include <Shlwapi.h>
|
||||
#undef StrCat // Don't let StrCat in string_util.h be renamed to lstrcatA
|
||||
#include <VersionHelpers.h>
|
||||
#include <Windows.h>
|
||||
#else
|
||||
#include <fcntl.h>
|
||||
#ifndef BENCHMARK_OS_FUCHSIA
|
||||
#include <sys/resource.h>
|
||||
#endif
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h> // this header must be included before 'sys/sysctl.h' to avoid compilation error on FreeBSD
|
||||
#include <unistd.h>
|
||||
|
|
@ -74,7 +77,7 @@ double MakeTime(FILETIME const& kernel_time, FILETIME const& user_time) {
|
|||
static_cast<double>(user.QuadPart)) *
|
||||
1e-7;
|
||||
}
|
||||
#else
|
||||
#elif !defined(BENCHMARK_OS_FUCHSIA)
|
||||
double MakeTime(struct rusage const& ru) {
|
||||
return (static_cast<double>(ru.ru_utime.tv_sec) +
|
||||
static_cast<double>(ru.ru_utime.tv_usec) * 1e-6 +
|
||||
|
|
@ -162,6 +165,10 @@ double ThreadCPUUsage() {
|
|||
// RTEMS doesn't support CLOCK_THREAD_CPUTIME_ID. See
|
||||
// https://github.com/RTEMS/rtems/blob/master/cpukit/posix/src/clockgettime.c
|
||||
return ProcessCPUUsage();
|
||||
#elif defined(BENCHMARK_OS_SOLARIS)
|
||||
struct rusage ru;
|
||||
if (getrusage(RUSAGE_LWP, &ru) == 0) return MakeTime(ru);
|
||||
DiagnoseAndExit("getrusage(RUSAGE_LWP, ...) failed");
|
||||
#elif defined(CLOCK_THREAD_CPUTIME_ID)
|
||||
struct timespec ts;
|
||||
if (clock_gettime(CLOCK_THREAD_CPUTIME_ID, &ts) == 0) return MakeTime(ts);
|
||||
|
|
@ -186,7 +193,6 @@ std::string DateTimeString(bool local) {
|
|||
std::strftime(storage, sizeof(storage), "%x %X", ::localtime(&now));
|
||||
#else
|
||||
std::tm timeinfo;
|
||||
std::memset(&timeinfo, 0, sizeof(std::tm));
|
||||
::localtime_r(&now, &timeinfo);
|
||||
written = std::strftime(storage, sizeof(storage), "%F %T", &timeinfo);
|
||||
#endif
|
||||
|
|
@ -195,7 +201,6 @@ std::string DateTimeString(bool local) {
|
|||
written = std::strftime(storage, sizeof(storage), "%x %X", ::gmtime(&now));
|
||||
#else
|
||||
std::tm timeinfo;
|
||||
std::memset(&timeinfo, 0, sizeof(std::tm));
|
||||
::gmtime_r(&now, &timeinfo);
|
||||
written = std::strftime(storage, sizeof(storage), "%F %T", &timeinfo);
|
||||
#endif
|
||||
|
|
|
|||
0
benchmarks/thirdparty/benchmark/src/timers.h
vendored
Normal file → Executable file
0
benchmarks/thirdparty/benchmark/src/timers.h
vendored
Normal file → Executable file
Loading…
Add table
Add a link
Reference in a new issue