|
| 1 | +#include <tbb/task_scheduler_init.h> |
| 2 | + |
| 3 | +#include "benchmark/benchmark.h" |
| 4 | +#include "common/scoped_timer.h" |
| 5 | +#include "execution/execution_util.h" |
| 6 | +#include "execution/vm/module.h" |
| 7 | +#include "main/db_main.h" |
| 8 | +#include "settings/settings_manager.h" |
| 9 | +#include "test_util/tpch/workload.h" |
| 10 | + |
| 11 | +namespace noisepage::tpch { |
| 12 | +class TPCHBenchmark : public benchmark::Fixture { |
| 13 | + public: |
| 14 | + const bool print_exec_info_ = true; |
| 15 | + const double threshold_ = 0.1; |
| 16 | + const uint64_t min_iterations_per_query_ = 10; |
| 17 | + const uint64_t max_iterations_per_query_ = 10; |
| 18 | + const int32_t threads_ = tbb::task_scheduler_init::default_num_threads(); |
| 19 | + const execution::vm::ExecutionMode mode_ = execution::vm::ExecutionMode::Interpret; |
| 20 | + |
| 21 | + std::unique_ptr<DBMain> db_main_; |
| 22 | + std::unique_ptr<tpch::Workload> tpch_workload_; |
| 23 | + |
| 24 | + const std::string tpch_table_root_ = "/Users/dpatra/Research/NoisePage-Support/TPCH/SF0.01/"; |
| 25 | + const std::string tpch_database_name_ = "tpch_db"; |
| 26 | + |
| 27 | + void SetUp(const benchmark::State &state) final { |
| 28 | + execution::ExecutionUtil::InitTPL(); |
| 29 | + |
| 30 | + // Set up database |
| 31 | + std::unordered_map<settings::Param, settings::ParamInfo> param_map; |
| 32 | + settings::SettingsManager::ConstructParamMap(param_map); |
| 33 | + auto db_main_builder = DBMain::Builder().SetUseGC(true) |
| 34 | + .SetUseCatalog(true) |
| 35 | + .SetUseGCThread(true) |
| 36 | + .SetUseSettingsManager(true) |
| 37 | + .SetSettingsParameterMap(std::move(param_map)); |
| 38 | + db_main_ = db_main_builder.Build(); |
| 39 | + |
| 40 | + // Set up metrics manager |
| 41 | + auto metrics_manager = db_main_->GetMetricsManager(); |
| 42 | + metrics_manager->EnableMetric(metrics::MetricsComponent::EXECUTION_PIPELINE); |
| 43 | + metrics_manager->SetMetricSampleInterval(metrics::MetricsComponent::EXECUTION_PIPELINE, 0); |
| 44 | + |
| 45 | + // Load the TPCH tables and compile the queries |
| 46 | + tpch_workload_ = std::make_unique<tpch::Workload>(common::ManagedPointer<DBMain>(db_main_), tpch_database_name_, |
| 47 | + tpch_table_root_, tpch::Workload::BenchmarkType::TPCH, threads_); |
| 48 | + } |
| 49 | + |
| 50 | + void TearDown(const benchmark::State &state) final { |
| 51 | + execution::ExecutionUtil::ShutdownTPL(); |
| 52 | + // free db main here so we don't need to use the loggers anymore |
| 53 | + db_main_.reset(); |
| 54 | + } |
| 55 | +}; |
| 56 | + |
| 57 | +// NOLINTNEXTLINE |
| 58 | +BENCHMARK_DEFINE_F(TPCHBenchmark, StabilizeBenchmark)(benchmark::State &state) { |
| 59 | + // Run benchmark for each query independently |
| 60 | + auto num_queries = tpch_workload_->GetQueryNum(); |
| 61 | + |
| 62 | + for (auto _ : state) { |
| 63 | + // Overall totals |
| 64 | + uint64_t queries_run = 0, total_time = 0; |
| 65 | + for (uint32_t i = 0; i < num_queries; i++) { |
| 66 | + // Single query running totals |
| 67 | + double old_avg = 0, avg = 0; |
| 68 | + double total = 0; |
| 69 | + uint64_t iterations = 0; |
| 70 | + // Iterate at least until min_iterations_per_query and at most until max_iterations_per_query and until average |
| 71 | + // stabilizes |
| 72 | + while ((iterations < min_iterations_per_query_) || |
| 73 | + ((abs(avg - old_avg) > threshold_) && (iterations < max_iterations_per_query_))) { |
| 74 | + old_avg = avg; |
| 75 | + total += tpch_workload_->TimeQuery(i, mode_, print_exec_info_); |
| 76 | + iterations++; |
| 77 | + avg = total / iterations; |
| 78 | + } |
| 79 | + |
| 80 | + if (print_exec_info_) { |
| 81 | + std::cout << tpch_workload_->GetQueryName(i) << " took " << iterations |
| 82 | + << " iterations with an average execution time of " << avg << std::endl; |
| 83 | + } |
| 84 | + |
| 85 | + queries_run += iterations; |
| 86 | + total_time += total; |
| 87 | + } |
| 88 | + state.SetIterationTime(total_time); |
| 89 | + state.SetItemsProcessed(queries_run); |
| 90 | + } |
| 91 | + |
| 92 | + // Free the workload here so we don't need to use the loggers anymore |
| 93 | + tpch_workload_.reset(); |
| 94 | +} |
| 95 | + |
| 96 | +// NOLINTNEXTLINE |
| 97 | +BENCHMARK_DEFINE_F(TPCHBenchmark, RuntimeBenchmark)(benchmark::State &state) { |
| 98 | + // Run benchmark for each query independently |
| 99 | + auto num_queries = tpch_workload_->GetQueryNum(); |
| 100 | + |
| 101 | + for (auto _ : state) { |
| 102 | + // Overall totals |
| 103 | + uint64_t queries_run = 0, total_time = 0; |
| 104 | + for (uint64_t iterations = 0; iterations < min_iterations_per_query_; iterations++) { |
| 105 | + // Iterate to min_iterations_per_query |
| 106 | + for (uint32_t i = 0; i < num_queries; i++) { |
| 107 | + total_time += tpch_workload_->TimeQuery(i, mode_, print_exec_info_); |
| 108 | + queries_run++; |
| 109 | + } |
| 110 | + } |
| 111 | + state.SetIterationTime(total_time); |
| 112 | + state.SetItemsProcessed(queries_run); |
| 113 | + } |
| 114 | + |
| 115 | + // Free the workload here so we don't need to use the loggers anymore |
| 116 | + tpch_workload_.reset(); |
| 117 | +} |
| 118 | + |
| 119 | +//BENCHMARK_REGISTER_F(TPCHBenchmark, StabilizeBenchmark)->Unit(benchmark::kMillisecond)->UseManualTime()->Iterations(1); |
| 120 | +BENCHMARK_REGISTER_F(TPCHBenchmark, RuntimeBenchmark)->Unit(benchmark::kMillisecond)->UseManualTime()->Iterations(1); |
| 121 | +} // namespace tpch |
0 commit comments