From 616964f65c2a676cb6a745c1b64dfc08d8e8d067 Mon Sep 17 00:00:00 2001 From: FritzFlorian Date: Fri, 29 May 2020 17:00:37 +0200 Subject: [PATCH] Sync benchmark runner. --- extern/benchmark_runner/benchmark_runner.h | 94 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 86 insertions(+), 8 deletions(-) diff --git a/extern/benchmark_runner/benchmark_runner.h b/extern/benchmark_runner/benchmark_runner.h index 37a2ac6..2a399b3 100644 --- a/extern/benchmark_runner/benchmark_runner.h +++ b/extern/benchmark_runner/benchmark_runner.h @@ -10,6 +10,14 @@ #include #include #include +#include +#include + +#include +#include +#include +#include +#include using namespace std; @@ -21,9 +29,16 @@ class benchmark_runner { chrono::steady_clock::time_point last_start_time_; vector times_; + map> custom_stats_; + void print_statistics() { long time_sum = std::accumulate(times_.begin(), times_.end(), 0l); cout << "Average Runtime (us): " << (time_sum / times_.size()) << endl; + + for (auto &iter : custom_stats_) { + long custom_stat_sum = std::accumulate(iter.second.begin(), iter.second.end(), 0l); + cout << "Average " << iter.first << ": " << (custom_stat_sum / times_.size()) << endl; + } } inline bool file_exists(const std::string &name) { @@ -32,17 +47,53 @@ class benchmark_runner { } public: - benchmark_runner(string csv_path, string csv_name, int num_measurements = 10000) : csv_path_{std::move(csv_path)}, - csv_name_{std::move(csv_name)}, - times_{} { + benchmark_runner(string csv_path, string csv_name) : csv_path_{std::move(csv_path)}, + csv_name_{std::move(csv_name)}, + times_{} { string command = "mkdir -p " + csv_path_; int res = system(command.c_str()); if (res) { cout << "Error while creating directory!" << endl; exit(1); } + } + + /** + * Queries the pages used by the current process. + * Splits between private and shared pages. + * + * @return Tuple(private_pages, shared_pages) used by the process. + */ + static std::pair query_process_memory_pages() { + pid_t my_pid = getpid(); + std::ostringstream proc_stats_path_builder; + proc_stats_path_builder << "/proc/" << my_pid << "/smaps_rollup"; + std::string proc_stats_path = proc_stats_path_builder.str(); + + std::ifstream proc_stats_file{proc_stats_path}; + + std::string line; + unsigned long total_shared = 0; + unsigned long total_private = 0; + while (std::getline(proc_stats_file, line)) { + std::stringstream line_input(line); + std::string type; + unsigned long size; + line_input >> type >> size; + + if (type.find("Shared") != std::string::npos) { + total_shared += size; + } + if (type.find("Private") != std::string::npos) { + total_private += size; + } + } + + return std::make_pair(total_private, total_shared); + } - times_.reserve(num_measurements); + void add_custom_stats_field(const string name) { + custom_stats_.insert({name, {}}); } static void read_args(int argc, char **argv, int &num_threads, string &path) { @@ -65,22 +116,35 @@ class benchmark_runner { auto end_time = chrono::steady_clock::now(); long time = chrono::duration_cast(end_time - last_start_time_).count(); times_.emplace_back(time); + + for (auto &iter : custom_stats_) { + iter.second.emplace_back(0); + } + } + + void store_custom_stat(const string &name, long value) { + auto &stat_vector = custom_stats_[name]; + stat_vector[stat_vector.size() - 1] = value; } void run_iterations(int count, const function measure, int warmup_count, - const function prepare = []() {}) { + const function prepare = []() {}, + const function finish = []() {}) { for (int i = 0; i < warmup_count; i++) { prepare(); measure(); } for (int i = 0; i < count; i++) { + using namespace std::literals; + this_thread::sleep_for(100us); prepare(); start_iteration(); measure(); end_iteration(); + finish(); } } @@ -94,15 +158,29 @@ class benchmark_runner { { // Scope for output file ofstream o(full_filename, std::fstream::out | std::fstream::app); + if (write_header) { - o << "runtime_us" << endl; + o << "runtime_us"; + for (auto &iter : custom_stats_) { + o << ";" << iter.first; + } + o << endl; } - for (auto time : times_) { - o << time << endl; + + // TODO: make this more efficient + for (size_t i = 0; i < times_.size(); i++) { + o << times_[i]; + for (auto &iter : custom_stats_) { + o << ";" << iter.second[i]; + } + o << endl; } } // End Scope for output file times_.clear(); + for (auto &iter : custom_stats_) { + iter.second.clear(); + } } }; -- libgit2 0.26.0