diff --git a/bench/db_bench.cc b/bench/db_bench.cc index a7ff9ec..cd0a952 100644 --- a/bench/db_bench.cc +++ b/bench/db_bench.cc @@ -182,38 +182,52 @@ enum OperationType : unsigned char { kUpdate, }; -class BenchmarkLogger : public CSV { +class BenchmarkLogger { private: struct hist { + int id; std::string name; std::string histogram; }; - + int id = 0; std::vector histograms; + CSV csv = CSV("id"); public: - using CSV::insert; - - BenchmarkLogger() : CSV("Benchmark"){}; - void insert(std::string name, Histogram histogram) { - histograms.push_back({name, histogram.ToString()}); + histograms.push_back({id, name, histogram.ToString()}); std::vector percentiles = {50, 75, 90, 99.9, 99.99}; for (double &percentile : percentiles) { - insert(name, "Percentilie P" + std::to_string(percentile), - histogram.Percentile(percentile)); + csv.insert(id, "Percentilie P" + std::to_string(percentile) + " [micros/op]", + histogram.Percentile(percentile)); } - insert(name, "Median", histogram.Median()); + csv.insert(id, "Median [micros/op]", histogram.Median()); + } + template + void insert(std::string column, T data) + { + csv.insert(id, column, data); } void print_histogram() { std::cout << "------------------------------------------------" << std::endl; for (auto &histogram : histograms) { - std::cout << histogram.name << std::endl << histogram.histogram << std::endl; + std::cout << "benchmark: " << histogram.id << ", " << histogram.name << std::endl + << histogram.histogram << std::endl; } } + + void print() + { + csv.print(); + } + + void next_benchmark() + { + id++; + } }; class Stats { @@ -461,12 +475,12 @@ class Benchmark { void PrintHeader() { PrintEnvironment(); - logger.insert(name.ToString(), "Path", FLAGS_db); - logger.insert(name.ToString(), "Engine", engine); - logger.insert(name.ToString(), "Keys [bytes each]", FLAGS_key_size); - logger.insert(name.ToString(), "Values [bytes each]", FLAGS_value_size); - logger.insert(name.ToString(), "Entries", num_); - logger.insert(name.ToString(), "RawSize [MB (estimated)]", + logger.insert("Path", FLAGS_db); + logger.insert("Engine", engine); + logger.insert("Keys [bytes each]", FLAGS_key_size); + logger.insert("Values [bytes each]", FLAGS_value_size); + logger.insert("Entries", num_); + logger.insert("RawSize [MB (estimated)]", ((static_cast(FLAGS_key_size + FLAGS_value_size) * num_) / 1048576.0)); PrintWarnings(); } @@ -486,8 +500,7 @@ class Benchmark { #if defined(__linux) time_t now = time(NULL); auto formatted_time = std::string(ctime(&now)); - logger.insert(name.ToString(), - "Date:", formatted_time.erase(formatted_time.find_last_not_of("\n"))); + logger.insert("Date:", formatted_time.erase(formatted_time.find_last_not_of("\n"))); FILE *cpuinfo = fopen("/proc/cpuinfo", "r"); if (cpuinfo != NULL) { @@ -510,9 +523,9 @@ class Benchmark { } } fclose(cpuinfo); - logger.insert(name.ToString(), "CPU", std::to_string(num_cpus)); - logger.insert(name.ToString(), "CPU model", cpu_type); - logger.insert(name.ToString(), "CPUCache", cache_size); + logger.insert("CPU", std::to_string(num_cpus)); + logger.insert("CPU model", cpu_type); + logger.insert("CPUCache", cache_size); } #endif } @@ -553,6 +566,8 @@ class Benchmark { } else { throw std::runtime_error("unknown benchmark: " + name.ToString()); } + logger.next_benchmark(); + logger.insert("Benchmark", name.ToString()); PrintHeader(); Open(fresh_db, name.ToString()); @@ -620,10 +635,10 @@ class Benchmark { arg[0].thread->stats.Merge(arg[i].thread->stats); } auto thread_stats = arg[0].thread->stats; - logger.insert(name.ToString(), "micros/op", thread_stats.get_micros_per_op()); - logger.insert(name.ToString(), "ops/sec", thread_stats.get_ops_per_sec()); - logger.insert(name.ToString(), "throughput [MB/s]", thread_stats.get_throughput()); - logger.insert(name.ToString(), "extra_data", thread_stats.get_extra_data()); + logger.insert("micros/op (avarage)", thread_stats.get_micros_per_op()); + logger.insert("ops/sec", thread_stats.get_ops_per_sec()); + logger.insert("throughput [MB/s]", thread_stats.get_throughput()); + logger.insert("extra_data", thread_stats.get_extra_data()); if (FLAGS_histogram) { logger.insert(name.ToString(), thread_stats.get_histogram()); } @@ -704,8 +719,7 @@ class Benchmark { if (pmempool_rm(FLAGS_db, PMEMPOOL_RM_FORCE) != 0) { throw std::runtime_error(std::string("Cannot remove pool: ") + FLAGS_db); } - logger.insert(name, "Remove [millis millis/op]", - ((g_env->NowMicros() - start) * 1e-3)); + logger.insert("Remove [millis/op]", ((g_env->NowMicros() - start) * 1e-3)); } kv_ = new pmem::kv::db; @@ -718,7 +732,7 @@ class Benchmark { USAGE.c_str()); exit(-42); } - logger.insert(name, "Open [millis/op]", ((g_env->NowMicros() - start) * 1e-3)); + logger.insert("Open [millis/op]", ((g_env->NowMicros() - start) * 1e-3)); } void DoWrite(ThreadState *thread, bool seq) diff --git a/bench/util/csv.h b/bench/util/csv.h index f626760..ab1e8b0 100644 --- a/bench/util/csv.h +++ b/bench/util/csv.h @@ -1,5 +1,5 @@ // SPDX-License-Identifier: Apache-2.0 -/* Copyright 2020, Intel Corporation */ +/* Copyright 2020-2021, Intel Corporation */ #pragma once @@ -9,11 +9,12 @@ #include #include +template class CSV { private: /* Hold data in two-dimensional map of strings: data_matrix[row][column] */ - std::map> data_matrix; + std::map> data_matrix; /* List of all columns, which is filled during inserts. Needed for * printing header and data in the same order. * */ @@ -22,19 +23,19 @@ class CSV { public: CSV(std::string id_column_name) : id_name(id_column_name){}; - void insert(std::string row, std::string column, std::string data) + void insert(IdType row, std::string column, std::string data) { columns.insert(column); data_matrix[row][column] = data; } - void insert(std::string row, std::string column, const char *data) + void insert(IdType row, std::string column, const char *data) { insert(row, column, std::string(data)); } template - void insert(std::string row, std::string column, T data) + void insert(IdType row, std::string column, T data) { insert(row, column, std::to_string(data)); }