static benchmark registration
This commit is contained in:
@@ -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
|
@@ -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();
|
|
||||||
}
|
|
@@ -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();
|
|
||||||
}
|
|
@@ -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();
|
|
||||||
}
|
|
@@ -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(); \
|
||||||
|
}
|
||||||
|
@@ -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
|
Reference in New Issue
Block a user