static benchmark registration

This commit is contained in:
Carl Pearson
2020-09-04 08:36:14 -06:00
parent 9fda681c37
commit 9fa6f3b811
6 changed files with 60 additions and 46 deletions

View File

@@ -94,7 +94,7 @@ The reported number of bytes will be bytes / second.
- [ ] max - [ ] max
- [ ] JSON reporter - [ ] JSON reporter
- [ ] Benchmark registration - [ ] Benchmark registration
- [ ] static - [x] static
- [ ] Auto-generated main function - [x] Auto-generated main function
- [x] function pointer - [x] function pointer
- [ ] lambda function - [ ] lambda function

View File

@@ -4,24 +4,19 @@
void allreduce(bench::State &state) { void allreduce(bench::State &state) {
const int rank = bench::world_rank();
const int size = bench::world_size();
const int rank = bench::world_rank(); const size_t sz = 100000;
const int size = bench::world_size();
const size_t sz = 1000; char *data = new char[sz];
for (auto _ : state) {
MPI_Allreduce(MPI_IN_PLACE, data, sz, MPI_BYTE, MPI_SUM, MPI_COMM_WORLD);
}
char *data = new char[sz]; state.set_bytes_processed(sz);
for (auto _ : state) { delete[] data;
MPI_Allreduce(MPI_IN_PLACE, data, sz, MPI_BYTE, MPI_SUM, MPI_COMM_WORLD);
}
state.set_bytes_processed(sz * size);
delete[] data;
} }
int main(int argc, char **argv) { BENCH(allreduce)->timing_max_rank();
bench::init(argc, argv); BENCH_MAIN()
bench::register_bench("allreduce", allreduce)->timing_max_rank();
bench::run_benchmarks();
bench::finalize();
}

View File

@@ -7,10 +7,5 @@ void empty(bench::State &state) {
} }
} }
int main(int argc, char **argv) { BENCH(empty)->timing_root_rank()->no_iter_barrier();
BENCH_MAIN()
bench::init(argc, argv);
bench::register_bench("empty", empty)->timing_root_rank()->no_iter_barrier();
bench::run_benchmarks();
bench::finalize();
}

View File

@@ -27,9 +27,5 @@ void pingpong(bench::State &state) {
delete[] rbuf; delete[] rbuf;
} }
int main(int argc, char **argv) { BENCH(pingpong)->timing_root_rank()->no_iter_barrier();
bench::init(argc, argv); BENCH_MAIN()
bench::register_bench("pingpong", pingpong)->timing_root_rank()->no_iter_barrier();
bench::run_benchmarks();
bench::finalize();
}

View File

@@ -86,8 +86,8 @@ public:
: iterations_(iterations), bytesProcessed_(0), error_(false), : iterations_(iterations), bytesProcessed_(0), error_(false),
timer_(timer), iterBarrier_(iterBarrier) {} timer_(timer), iterBarrier_(iterBarrier) {}
Iterator begin(); BENCH_ALWAYS_INLINE Iterator begin();
Iterator end(); BENCH_ALWAYS_INLINE Iterator end();
void start_running() { timer_->resume(); } void start_running() { timer_->resume(); }
void finish_running() { timer_->pause(); } void finish_running() { timer_->pause(); }
@@ -126,14 +126,14 @@ public:
#ifdef BENCH_USE_MPI #ifdef BENCH_USE_MPI
if (iterBarrier_) { if (iterBarrier_) {
// timing was paused in operator++
MPI_Barrier(MPI_COMM_WORLD); MPI_Barrier(MPI_COMM_WORLD);
// timing was paused in operator++
resume_timing(); resume_timing();
} }
#endif #endif
// if (__builtin_expect(remaining_ != 0, true)) { // if (__builtin_expect(remaining_ != 0, true)) {
if (remaining_ != 0, false) { if (remaining_ != 0) {
return true; return true;
} }
parent_->finish_running(); parent_->finish_running();
@@ -144,7 +144,7 @@ public:
#ifdef BENCH_USE_MPI #ifdef BENCH_USE_MPI
if (iterBarrier_) { if (iterBarrier_) {
// pause timer before barrier // pause timer before barrier, to be resumed in operator!=
pause_timing(); pause_timing();
} }
#endif #endif
@@ -157,8 +157,8 @@ public:
BENCH_ALWAYS_INLINE void resume_timing() { parent_->timer_->resume(); } BENCH_ALWAYS_INLINE void resume_timing() { parent_->timer_->resume(); }
}; };
inline State::Iterator State::begin() { return State::Iterator(this); } inline BENCH_ALWAYS_INLINE State::Iterator State::begin() { return State::Iterator(this); }
inline State::Iterator State::end() { inline BENCH_ALWAYS_INLINE State::Iterator State::end() {
start_running(); start_running();
return State::Iterator(); return State::Iterator();
} }
@@ -174,11 +174,13 @@ public:
bool iter_barrier() { return iterBarrier_; } bool iter_barrier() { return iterBarrier_; }
// only record time at rank 0 // only record time at rank 0
Benchmark *timing_root_rank() { Benchmark *timing_root_rank() {
if (timer_) { if (timer_) {
delete timer_; delete timer_;
} }
// FIXME: during static registration, this will be before MPI_Init
if (world_rank() == 0) { if (world_rank() == 0) {
timer_ = new WallTimer(); timer_ = new WallTimer();
} else { } else {
@@ -204,7 +206,8 @@ private:
bool iterBarrier_; bool iterBarrier_;
}; };
extern std::vector<Benchmark *> benchmarks; // get all registered benchmarks
std::vector<Benchmark *> &benchmarks();
typedef void (*Function)(State &); typedef void (*Function)(State &);
@@ -228,4 +231,27 @@ Benchmark *RegisterBenchmark(const char *name, Fn &&fn, Args &&... args) {
} }
#endif #endif
} // namespace bench } // namespace bench
#if defined(__COUNTER__) && (__COUNTER__ + 1 == __COUNTER__ + 0)
#define BENCH_PRIVATE_UNIQUE_ID __COUNTER__
#else
#define BENCH_PRIVATE_UNIQUE_ID __LINE__
#endif
// Helpers for generating unique variable names
#define BENCH_UNIQUE_NAME(n) \
BENCH_PRIVATE_CONCAT(_bench_, BENCH_PRIVATE_UNIQUE_ID, n)
#define BENCH_PRIVATE_CONCAT(a, b, c) BENCH_PRIVATE_CONCAT2(a, b, c)
#define BENCH_PRIVATE_CONCAT2(a, b, c) a##b##c
#define BENCH_DECLARE(x) static bench::Benchmark *BENCH_UNIQUE_NAME(x)
#define BENCH(x) BENCH_DECLARE(x) = bench::register_bench(#x, x)
#define BENCH_MAIN() \
int main(int argc, char **argv) { \
bench::init(argc, argv); \
bench::run_benchmarks(); \
bench::finalize(); \
}

View File

@@ -9,6 +9,11 @@
namespace bench { namespace bench {
std::vector<Benchmark *> &benchmarks() {
static std::vector<Benchmark *> benchmarks;
return benchmarks;
}
void init(int &argc, char **&argv) { void init(int &argc, char **&argv) {
#ifdef BENCH_USE_MPI #ifdef BENCH_USE_MPI
MPI_Init(&argc, &argv); MPI_Init(&argc, &argv);
@@ -41,7 +46,7 @@ int world_size() {
void run_benchmarks() { void run_benchmarks() {
for (Benchmark *benchmark : benchmarks) { for (Benchmark *benchmark : benchmarks()) {
if (0 == world_rank()) { if (0 == world_rank()) {
std::cerr << "running " << benchmark->name() << "\n"; std::cerr << "running " << benchmark->name() << "\n";
} }
@@ -68,7 +73,6 @@ void run_benchmarks() {
double sElapsed = nsElapsed / 1e9; double sElapsed = nsElapsed / 1e9;
double bytes = state.bytes_processed(); double bytes = state.bytes_processed();
std::cout << benchmark->name() << ": " << nsElapsed << "ns"; std::cout << benchmark->name() << ": " << nsElapsed << "ns";
if (state.bytes_processed()) { if (state.bytes_processed()) {
std::cout << " " << bytes / sElapsed << "B/s"; std::cout << " " << bytes / sElapsed << "B/s";
@@ -79,12 +83,10 @@ void run_benchmarks() {
} }
Benchmark *register_bench(const char *name, Function fn) { Benchmark *register_bench(const char *name, Function fn) {
benchmarks.push_back(new FunctionBenchmark(name, fn)); benchmarks().push_back(new FunctionBenchmark(name, fn));
return benchmarks.back(); return benchmarks().back();
} }
void FunctionBenchmark::run(State &state) { fn_(state); } void FunctionBenchmark::run(State &state) { fn_(state); }
/*extern*/ std::vector<Benchmark *> benchmarks;
} // namespace bench } // namespace bench