⬆️ 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
171
benchmarks/thirdparty/benchmark/include/benchmark/benchmark.h
vendored
Normal file → Executable file
171
benchmarks/thirdparty/benchmark/include/benchmark/benchmark.h
vendored
Normal file → Executable file
|
|
@ -172,6 +172,7 @@ BENCHMARK(BM_test)->Unit(benchmark::kMillisecond);
|
|||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <cstddef>
|
||||
#include <iosfwd>
|
||||
|
|
@ -291,7 +292,7 @@ BENCHMARK_UNUSED static int stream_init_anchor = InitializeStreams();
|
|||
|
||||
|
||||
#if (!defined(__GNUC__) && !defined(__clang__)) || defined(__pnacl__) || \
|
||||
defined(EMSCRIPTN)
|
||||
defined(__EMSCRIPTEN__)
|
||||
# define BENCHMARK_HAS_NO_INLINE_ASSEMBLY
|
||||
#endif
|
||||
|
||||
|
|
@ -302,15 +303,20 @@ BENCHMARK_UNUSED static int stream_init_anchor = InitializeStreams();
|
|||
// See: https://youtu.be/nXaxk27zwlk?t=2441
|
||||
#ifndef BENCHMARK_HAS_NO_INLINE_ASSEMBLY
|
||||
template <class Tp>
|
||||
inline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp const& value) {
|
||||
// Clang doesn't like the 'X' constraint on `value` and certain GCC versions
|
||||
// don't like the 'g' constraint. Attempt to placate them both.
|
||||
inline BENCHMARK_ALWAYS_INLINE
|
||||
void DoNotOptimize(Tp const& value) {
|
||||
asm volatile("" : : "r,m"(value) : "memory");
|
||||
}
|
||||
|
||||
template <class Tp>
|
||||
inline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp& value) {
|
||||
#if defined(__clang__)
|
||||
asm volatile("" : : "g"(value) : "memory");
|
||||
asm volatile("" : "+r,m"(value) : : "memory");
|
||||
#else
|
||||
asm volatile("" : : "i,r,m"(value) : "memory");
|
||||
asm volatile("" : "+m,r"(value) : : "memory");
|
||||
#endif
|
||||
}
|
||||
|
||||
// Force the compiler to flush pending writes to global memory. Acts as an
|
||||
// effective read/write barrier
|
||||
inline BENCHMARK_ALWAYS_INLINE void ClobberMemory() {
|
||||
|
|
@ -379,7 +385,7 @@ enum BigO { oNone, o1, oN, oNSquared, oNCubed, oLogN, oNLogN, oAuto, oLambda };
|
|||
|
||||
// BigOFunc is passed to a benchmark in order to specify the asymptotic
|
||||
// computational complexity for the benchmark.
|
||||
typedef double(BigOFunc)(int);
|
||||
typedef double(BigOFunc)(int64_t);
|
||||
|
||||
// StatisticsFunc is passed to a benchmark in order to compute some descriptive
|
||||
// statistics over all the measurements of some type
|
||||
|
|
@ -429,16 +435,19 @@ class State {
|
|||
// Returns true if the benchmark should continue through another iteration.
|
||||
// NOTE: A benchmark may not return from the test until KeepRunning() has
|
||||
// returned false.
|
||||
bool KeepRunning() {
|
||||
if (BENCHMARK_BUILTIN_EXPECT(!started_, false)) {
|
||||
StartKeepRunning();
|
||||
}
|
||||
bool const res = (--total_iterations_ != 0);
|
||||
if (BENCHMARK_BUILTIN_EXPECT(!res, false)) {
|
||||
FinishKeepRunning();
|
||||
}
|
||||
return res;
|
||||
}
|
||||
bool KeepRunning();
|
||||
|
||||
// Returns true iff the benchmark should run n more iterations.
|
||||
// REQUIRES: 'n' > 0.
|
||||
// NOTE: A benchmark must not return from the test until KeepRunningBatch()
|
||||
// has returned false.
|
||||
// NOTE: KeepRunningBatch() may overshoot by up to 'n' iterations.
|
||||
//
|
||||
// Intended usage:
|
||||
// while (state.KeepRunningBatch(1000)) {
|
||||
// // process 1000 elements
|
||||
// }
|
||||
bool KeepRunningBatch(size_t n);
|
||||
|
||||
// REQUIRES: timer is running and 'SkipWithError(...)' has not been called
|
||||
// by the current thread.
|
||||
|
|
@ -505,10 +514,10 @@ class State {
|
|||
//
|
||||
// REQUIRES: a benchmark has exited its benchmarking loop.
|
||||
BENCHMARK_ALWAYS_INLINE
|
||||
void SetBytesProcessed(size_t bytes) { bytes_processed_ = bytes; }
|
||||
void SetBytesProcessed(int64_t bytes) { bytes_processed_ = bytes; }
|
||||
|
||||
BENCHMARK_ALWAYS_INLINE
|
||||
size_t bytes_processed() const { return bytes_processed_; }
|
||||
int64_t bytes_processed() const { return bytes_processed_; }
|
||||
|
||||
// If this routine is called with complexity_n > 0 and complexity report is
|
||||
// requested for the
|
||||
|
|
@ -516,10 +525,10 @@ class State {
|
|||
// and complexity_n will
|
||||
// represent the length of N.
|
||||
BENCHMARK_ALWAYS_INLINE
|
||||
void SetComplexityN(int complexity_n) { complexity_n_ = complexity_n; }
|
||||
void SetComplexityN(int64_t complexity_n) { complexity_n_ = complexity_n; }
|
||||
|
||||
BENCHMARK_ALWAYS_INLINE
|
||||
int complexity_length_n() { return complexity_n_; }
|
||||
int64_t complexity_length_n() { return complexity_n_; }
|
||||
|
||||
// If this routine is called with items > 0, then an items/s
|
||||
// label is printed on the benchmark report line for the currently
|
||||
|
|
@ -528,10 +537,10 @@ class State {
|
|||
//
|
||||
// REQUIRES: a benchmark has exited its benchmarking loop.
|
||||
BENCHMARK_ALWAYS_INLINE
|
||||
void SetItemsProcessed(size_t items) { items_processed_ = items; }
|
||||
void SetItemsProcessed(int64_t items) { items_processed_ = items; }
|
||||
|
||||
BENCHMARK_ALWAYS_INLINE
|
||||
size_t items_processed() const { return items_processed_; }
|
||||
int64_t items_processed() const { return items_processed_; }
|
||||
|
||||
// If this routine is called, the specified label is printed at the
|
||||
// end of the benchmark report line for the currently executing
|
||||
|
|
@ -539,7 +548,7 @@ class State {
|
|||
// static void BM_Compress(benchmark::State& state) {
|
||||
// ...
|
||||
// double compress = input_size / output_size;
|
||||
// state.SetLabel(StringPrintf("compress:%.1f%%", 100.0*compression));
|
||||
// state.SetLabel(StrFormat("compress:%.1f%%", 100.0*compression));
|
||||
// }
|
||||
// Produces output that looks like:
|
||||
// BM_Compress 50 50 14115038 compress:27.3%
|
||||
|
|
@ -553,34 +562,52 @@ class State {
|
|||
|
||||
// Range arguments for this run. CHECKs if the argument has been set.
|
||||
BENCHMARK_ALWAYS_INLINE
|
||||
int range(std::size_t pos = 0) const {
|
||||
int64_t range(std::size_t pos = 0) const {
|
||||
assert(range_.size() > pos);
|
||||
return range_[pos];
|
||||
}
|
||||
|
||||
BENCHMARK_DEPRECATED_MSG("use 'range(0)' instead")
|
||||
int range_x() const { return range(0); }
|
||||
int64_t range_x() const { return range(0); }
|
||||
|
||||
BENCHMARK_DEPRECATED_MSG("use 'range(1)' instead")
|
||||
int range_y() const { return range(1); }
|
||||
int64_t range_y() const { return range(1); }
|
||||
|
||||
BENCHMARK_ALWAYS_INLINE
|
||||
size_t iterations() const { return (max_iterations - total_iterations_) + 1; }
|
||||
size_t iterations() const {
|
||||
if (BENCHMARK_BUILTIN_EXPECT(!started_, false)) {
|
||||
return 0;
|
||||
}
|
||||
return max_iterations - total_iterations_ + batch_leftover_;
|
||||
}
|
||||
|
||||
private:
|
||||
bool started_;
|
||||
bool finished_;
|
||||
private: // items we expect on the first cache line (ie 64 bytes of the struct)
|
||||
|
||||
// When total_iterations_ is 0, KeepRunning() and friends will return false.
|
||||
// May be larger than max_iterations.
|
||||
size_t total_iterations_;
|
||||
|
||||
std::vector<int> range_;
|
||||
// When using KeepRunningBatch(), batch_leftover_ holds the number of
|
||||
// iterations beyond max_iters that were run. Used to track
|
||||
// completed_iterations_ accurately.
|
||||
size_t batch_leftover_;
|
||||
|
||||
size_t bytes_processed_;
|
||||
size_t items_processed_;
|
||||
|
||||
int complexity_n_;
|
||||
public:
|
||||
const size_t max_iterations;
|
||||
|
||||
private:
|
||||
bool started_;
|
||||
bool finished_;
|
||||
bool error_occurred_;
|
||||
|
||||
private: // items we don't need on the first cache line
|
||||
std::vector<int64_t> range_;
|
||||
|
||||
int64_t bytes_processed_;
|
||||
int64_t items_processed_;
|
||||
|
||||
int64_t complexity_n_;
|
||||
|
||||
public:
|
||||
// Container for user-defined counters.
|
||||
UserCounters counters;
|
||||
|
|
@ -588,27 +615,69 @@ class State {
|
|||
const int thread_index;
|
||||
// Number of threads concurrently executing the benchmark.
|
||||
const int threads;
|
||||
const size_t max_iterations;
|
||||
|
||||
|
||||
// TODO(EricWF) make me private
|
||||
State(size_t max_iters, const std::vector<int>& ranges, int thread_i,
|
||||
State(size_t max_iters, const std::vector<int64_t>& ranges, int thread_i,
|
||||
int n_threads, internal::ThreadTimer* timer,
|
||||
internal::ThreadManager* manager);
|
||||
|
||||
private:
|
||||
void StartKeepRunning();
|
||||
// Implementation of KeepRunning() and KeepRunningBatch().
|
||||
// is_batch must be true unless n is 1.
|
||||
bool KeepRunningInternal(size_t n, bool is_batch);
|
||||
void FinishKeepRunning();
|
||||
internal::ThreadTimer* timer_;
|
||||
internal::ThreadManager* manager_;
|
||||
BENCHMARK_DISALLOW_COPY_AND_ASSIGN(State);
|
||||
};
|
||||
|
||||
inline BENCHMARK_ALWAYS_INLINE
|
||||
bool State::KeepRunning() {
|
||||
return KeepRunningInternal(1, /*is_batch=*/ false);
|
||||
}
|
||||
|
||||
inline BENCHMARK_ALWAYS_INLINE
|
||||
bool State::KeepRunningBatch(size_t n) {
|
||||
return KeepRunningInternal(n, /*is_batch=*/ true);
|
||||
}
|
||||
|
||||
inline BENCHMARK_ALWAYS_INLINE
|
||||
bool State::KeepRunningInternal(size_t n, bool is_batch) {
|
||||
// total_iterations_ is set to 0 by the constructor, and always set to a
|
||||
// nonzero value by StartKepRunning().
|
||||
assert(n > 0);
|
||||
// n must be 1 unless is_batch is true.
|
||||
assert(is_batch || n == 1);
|
||||
if (BENCHMARK_BUILTIN_EXPECT(total_iterations_ >= n, true)) {
|
||||
total_iterations_ -= n;
|
||||
return true;
|
||||
}
|
||||
if (!started_) {
|
||||
StartKeepRunning();
|
||||
if (!error_occurred_ && total_iterations_ >= n) {
|
||||
total_iterations_-= n;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// For non-batch runs, total_iterations_ must be 0 by now.
|
||||
if (is_batch && total_iterations_ != 0) {
|
||||
batch_leftover_ = n - total_iterations_;
|
||||
total_iterations_ = 0;
|
||||
return true;
|
||||
}
|
||||
FinishKeepRunning();
|
||||
return false;
|
||||
}
|
||||
|
||||
struct State::StateIterator {
|
||||
struct BENCHMARK_UNUSED Value {};
|
||||
typedef std::forward_iterator_tag iterator_category;
|
||||
typedef Value value_type;
|
||||
typedef Value reference;
|
||||
typedef Value pointer;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
|
||||
private:
|
||||
friend class State;
|
||||
|
|
@ -670,7 +739,7 @@ class Benchmark {
|
|||
// Run this benchmark once with "x" as the extra argument passed
|
||||
// to the function.
|
||||
// REQUIRES: The function passed to the constructor must accept an arg1.
|
||||
Benchmark* Arg(int x);
|
||||
Benchmark* Arg(int64_t x);
|
||||
|
||||
// Run this benchmark with the given time unit for the generated output report
|
||||
Benchmark* Unit(TimeUnit unit);
|
||||
|
|
@ -678,23 +747,23 @@ class Benchmark {
|
|||
// Run this benchmark once for a number of values picked from the
|
||||
// range [start..limit]. (start and limit are always picked.)
|
||||
// REQUIRES: The function passed to the constructor must accept an arg1.
|
||||
Benchmark* Range(int start, int limit);
|
||||
Benchmark* Range(int64_t start, int64_t limit);
|
||||
|
||||
// Run this benchmark once for all values in the range [start..limit] with
|
||||
// specific step
|
||||
// REQUIRES: The function passed to the constructor must accept an arg1.
|
||||
Benchmark* DenseRange(int start, int limit, int step = 1);
|
||||
Benchmark* DenseRange(int64_t start, int64_t limit, int step = 1);
|
||||
|
||||
// Run this benchmark once with "args" as the extra arguments passed
|
||||
// to the function.
|
||||
// REQUIRES: The function passed to the constructor must accept arg1, arg2 ...
|
||||
Benchmark* Args(const std::vector<int>& args);
|
||||
Benchmark* Args(const std::vector<int64_t>& args);
|
||||
|
||||
// Equivalent to Args({x, y})
|
||||
// NOTE: This is a legacy C++03 interface provided for compatibility only.
|
||||
// New code should use 'Args'.
|
||||
Benchmark* ArgPair(int x, int y) {
|
||||
std::vector<int> args;
|
||||
Benchmark* ArgPair(int64_t x, int64_t y) {
|
||||
std::vector<int64_t> args;
|
||||
args.push_back(x);
|
||||
args.push_back(y);
|
||||
return Args(args);
|
||||
|
|
@ -703,7 +772,7 @@ class Benchmark {
|
|||
// Run this benchmark once for a number of values picked from the
|
||||
// ranges [start..limit]. (starts and limits are always picked.)
|
||||
// REQUIRES: The function passed to the constructor must accept arg1, arg2 ...
|
||||
Benchmark* Ranges(const std::vector<std::pair<int, int> >& ranges);
|
||||
Benchmark* Ranges(const std::vector<std::pair<int64_t, int64_t> >& ranges);
|
||||
|
||||
// Equivalent to ArgNames({name})
|
||||
Benchmark* ArgName(const std::string& name);
|
||||
|
|
@ -715,8 +784,8 @@ class Benchmark {
|
|||
// Equivalent to Ranges({{lo1, hi1}, {lo2, hi2}}).
|
||||
// NOTE: This is a legacy C++03 interface provided for compatibility only.
|
||||
// New code should use 'Ranges'.
|
||||
Benchmark* RangePair(int lo1, int hi1, int lo2, int hi2) {
|
||||
std::vector<std::pair<int, int> > ranges;
|
||||
Benchmark* RangePair(int64_t lo1, int64_t hi1, int64_t lo2, int64_t hi2) {
|
||||
std::vector<std::pair<int64_t, int64_t> > ranges;
|
||||
ranges.push_back(std::make_pair(lo1, hi1));
|
||||
ranges.push_back(std::make_pair(lo2, hi2));
|
||||
return Ranges(ranges);
|
||||
|
|
@ -823,15 +892,13 @@ class Benchmark {
|
|||
|
||||
int ArgsCnt() const;
|
||||
|
||||
static void AddRange(std::vector<int>* dst, int lo, int hi, int mult);
|
||||
|
||||
private:
|
||||
friend class BenchmarkFamilies;
|
||||
|
||||
std::string name_;
|
||||
ReportMode report_mode_;
|
||||
std::vector<std::string> arg_names_; // Args for all benchmark runs
|
||||
std::vector<std::vector<int> > args_; // Args for all benchmark runs
|
||||
std::vector<std::vector<int64_t> > args_; // Args for all benchmark runs
|
||||
TimeUnit time_unit_;
|
||||
int range_multiplier_;
|
||||
double min_time_;
|
||||
|
|
@ -1186,7 +1253,7 @@ class BenchmarkReporter {
|
|||
CPUInfo const& cpu_info;
|
||||
// The number of chars in the longest benchmark name.
|
||||
size_t name_field_width;
|
||||
|
||||
static const char *executable_name;
|
||||
Context();
|
||||
};
|
||||
|
||||
|
|
@ -1239,7 +1306,7 @@ class BenchmarkReporter {
|
|||
// Keep track of arguments to compute asymptotic complexity
|
||||
BigO complexity;
|
||||
BigOFunc* complexity_lambda;
|
||||
int complexity_n;
|
||||
int64_t complexity_n;
|
||||
|
||||
// what statistics to compute from the measurements
|
||||
const std::vector<Statistics>* statistics;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue