Skip to content

Commit 8ba24f1

Browse files
author
olegmak
committed
Refactor time measurement to use std::chrono::steady_clock in benchmark tools. Previously used gettimeofday can be adjusted backwards, resulting in incorrect measurements.
1 parent f0d9e37 commit 8ba24f1

4 files changed

Lines changed: 44 additions & 76 deletions

File tree

tools/bpm_bench/bpm_bench.cpp

Lines changed: 11 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -34,21 +34,13 @@
3434
#include "fmt/std.h"
3535
#include "storage/disk/disk_manager_memory.h"
3636

37-
#include <sys/time.h>
38-
39-
auto ClockMs() -> uint64_t {
40-
struct timeval tm;
41-
gettimeofday(&tm, nullptr);
42-
return static_cast<uint64_t>(tm.tv_sec * 1000) + static_cast<uint64_t>(tm.tv_usec / 1000);
43-
}
44-
4537
struct BpmTotalMetrics {
4638
uint64_t scan_cnt_{0};
4739
uint64_t get_cnt_{0};
48-
uint64_t start_time_{0};
40+
std::chrono::steady_clock::time_point start_time_;
4941
std::mutex mutex_;
5042

51-
void Begin() { start_time_ = ClockMs(); }
43+
void Begin() { start_time_ = std::chrono::steady_clock::now(); }
5244

5345
void ReportScan(uint64_t scan_cnt) {
5446
std::unique_lock<std::mutex> l(mutex_);
@@ -61,8 +53,8 @@ struct BpmTotalMetrics {
6153
}
6254

6355
void Report() {
64-
auto now = ClockMs();
65-
auto elapsed = now - start_time_;
56+
auto now = std::chrono::steady_clock::now();
57+
auto elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(now - start_time_).count();
6658
auto scan_per_sec = scan_cnt_ / static_cast<double>(elapsed) * 1000;
6759
auto get_per_sec = get_cnt_ / static_cast<double>(elapsed) * 1000;
6860

@@ -74,7 +66,7 @@ struct BpmTotalMetrics {
7466
};
7567

7668
struct BpmMetrics {
77-
uint64_t start_time_{0};
69+
std::chrono::steady_clock::time_point start_time_;
7870
uint64_t last_report_at_{0};
7971
uint64_t last_cnt_{0};
8072
uint64_t cnt_{0};
@@ -86,12 +78,12 @@ struct BpmMetrics {
8678

8779
void Tick() { cnt_ += 1; }
8880

89-
void Begin() { start_time_ = ClockMs(); }
81+
void Begin() { start_time_ = std::chrono::steady_clock::now(); }
9082

9183
void Report() {
92-
auto now = ClockMs();
93-
auto elapsed = now - start_time_;
94-
if (elapsed - last_report_at_ > 1000) {
84+
auto now = std::chrono::steady_clock::now();
85+
auto elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(now - start_time_).count();
86+
if (elapsed - last_report_at_ >= 1000) {
9587
fmt::print(stderr, "[{:5.2f}] {}: total_cnt={:<10} throughput={:<10.3f} avg_throughput={:<10.3f}\n",
9688
elapsed / 1000.0, reporter_, cnt_,
9789
(cnt_ - last_cnt_) / static_cast<double>(elapsed - last_report_at_) * 1000,
@@ -102,8 +94,8 @@ struct BpmMetrics {
10294
}
10395

10496
auto ShouldFinish() -> bool {
105-
auto now = ClockMs();
106-
return now - start_time_ > duration_ms_;
97+
auto now = std::chrono::steady_clock::now();
98+
return std::chrono::duration_cast<std::chrono::milliseconds>(now - start_time_).count() > duration_ms_;
10799
}
108100
};
109101

tools/btree_bench/btree_bench.cpp

Lines changed: 11 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -36,14 +36,6 @@
3636
#include "storage/index/generic_key.h"
3737
#include "test_util.h"
3838

39-
#include <sys/time.h>
40-
41-
auto ClockMs() -> uint64_t {
42-
struct timeval tm;
43-
gettimeofday(&tm, nullptr);
44-
return static_cast<uint64_t>(tm.tv_sec * 1000) + static_cast<uint64_t>(tm.tv_usec / 1000);
45-
}
46-
4739
static const size_t BUSTUB_READ_THREAD = 4;
4840
static const size_t BUSTUB_WRITE_THREAD = 2;
4941
// We should keep the BPM size large enough to hold all pages in memory, to minimize the dependency on P1.
@@ -55,10 +47,10 @@ static const size_t KEY_MODIFY_RANGE = 2048;
5547
struct BTreeTotalMetrics {
5648
uint64_t write_cnt_{0};
5749
uint64_t read_cnt_{0};
58-
uint64_t start_time_{0};
50+
std::chrono::steady_clock::time_point start_time_;
5951
std::mutex mutex_;
6052

61-
void Begin() { start_time_ = ClockMs(); }
53+
void Begin() { start_time_ = std::chrono::steady_clock::now(); }
6254

6355
void ReportWrite(uint64_t scan_cnt) {
6456
std::unique_lock<std::mutex> l(mutex_);
@@ -71,8 +63,8 @@ struct BTreeTotalMetrics {
7163
}
7264

7365
void Report() {
74-
auto now = ClockMs();
75-
auto elapsed = now - start_time_;
66+
auto now = std::chrono::steady_clock::now();
67+
auto elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(now - start_time_).count();
7668
auto write_per_sec = write_cnt_ / static_cast<double>(elapsed) * 1000;
7769
auto read_per_sec = read_cnt_ / static_cast<double>(elapsed) * 1000;
7870

@@ -84,7 +76,7 @@ struct BTreeTotalMetrics {
8476
};
8577

8678
struct BTreeMetrics {
87-
uint64_t start_time_{0};
79+
std::chrono::steady_clock::time_point start_time_;
8880
uint64_t last_report_at_{0};
8981
uint64_t last_cnt_{0};
9082
uint64_t cnt_{0};
@@ -96,12 +88,12 @@ struct BTreeMetrics {
9688

9789
void Tick() { cnt_ += 1; }
9890

99-
void Begin() { start_time_ = ClockMs(); }
91+
void Begin() { start_time_ = std::chrono::steady_clock::now(); }
10092

10193
void Report() {
102-
auto now = ClockMs();
103-
auto elapsed = now - start_time_;
104-
if (elapsed - last_report_at_ > 1000) {
94+
auto now = std::chrono::steady_clock::now();
95+
auto elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(now - start_time_).count();
96+
if (elapsed - last_report_at_ >= 1000) {
10597
fmt::print(stderr, "[{:5.2f}] {}: total_cnt={:<10} throughput={:<10.3f} avg_throughput={:<10.3f}\n",
10698
elapsed / 1000.0, reporter_, cnt_,
10799
(cnt_ - last_cnt_) / static_cast<double>(elapsed - last_report_at_) * 1000,
@@ -112,8 +104,8 @@ struct BTreeMetrics {
112104
}
113105

114106
auto ShouldFinish() -> bool {
115-
auto now = ClockMs();
116-
return now - start_time_ > duration_ms_;
107+
auto now = std::chrono::steady_clock::now();
108+
return std::chrono::duration_cast<std::chrono::milliseconds>(now - start_time_).count() > duration_ms_;
117109
}
118110
};
119111

tools/htable_bench/htable_bench.cpp

Lines changed: 11 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -36,14 +36,6 @@
3636
#include "storage/index/generic_key.h"
3737
#include "test_util.h"
3838

39-
#include <sys/time.h>
40-
41-
auto ClockMs() -> uint64_t {
42-
struct timeval tm;
43-
gettimeofday(&tm, nullptr);
44-
return static_cast<uint64_t>(tm.tv_sec * 1000) + static_cast<uint64_t>(tm.tv_usec / 1000);
45-
}
46-
4739
static const size_t BUSTUB_READ_THREAD = 5;
4840
static const size_t BUSTUB_WRITE_THREAD = 3;
4941
static const size_t BUSTUB_BPM_SIZE = 2048;
@@ -55,10 +47,10 @@ static const size_t HTABLE_DIRECTORY_DEPTH = 9;
5547
struct HTableTotalMetrics {
5648
uint64_t write_cnt_{0};
5749
uint64_t read_cnt_{0};
58-
uint64_t start_time_{0};
50+
std::chrono::steady_clock::time_point start_time_;
5951
std::mutex mutex_;
6052

61-
void Begin() { start_time_ = ClockMs(); }
53+
void Begin() { start_time_ = std::chrono::steady_clock::now(); }
6254

6355
void ReportWrite(uint64_t scan_cnt) {
6456
std::unique_lock<std::mutex> l(mutex_);
@@ -71,8 +63,8 @@ struct HTableTotalMetrics {
7163
}
7264

7365
void Report() {
74-
auto now = ClockMs();
75-
auto elapsed = now - start_time_;
66+
auto now = std::chrono::steady_clock::now();
67+
auto elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(now - start_time_).count();
7668
auto write_per_sec = write_cnt_ / static_cast<double>(elapsed) * 1000;
7769
auto read_per_sec = read_cnt_ / static_cast<double>(elapsed) * 1000;
7870

@@ -84,7 +76,7 @@ struct HTableTotalMetrics {
8476
};
8577

8678
struct HTableMetrics {
87-
uint64_t start_time_{0};
79+
std::chrono::steady_clock::time_point start_time_;
8880
uint64_t last_report_at_{0};
8981
uint64_t last_cnt_{0};
9082
uint64_t cnt_{0};
@@ -96,12 +88,12 @@ struct HTableMetrics {
9688

9789
void Tick() { cnt_ += 1; }
9890

99-
void Begin() { start_time_ = ClockMs(); }
91+
void Begin() { start_time_ = std::chrono::steady_clock::now(); }
10092

10193
void Report() {
102-
auto now = ClockMs();
103-
auto elapsed = now - start_time_;
104-
if (elapsed - last_report_at_ > 1000) {
94+
auto now = std::chrono::steady_clock::now();
95+
auto elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(now - start_time_).count();
96+
if (elapsed - last_report_at_ >= 1000) {
10597
fmt::print(stderr, "[{:5.2f}] {}: total_cnt={:<10} throughput={:<10.3f} avg_throughput={:<10.3f}\n",
10698
elapsed / 1000.0, reporter_, cnt_,
10799
(cnt_ - last_cnt_) / static_cast<double>(elapsed - last_report_at_) * 1000,
@@ -112,8 +104,8 @@ struct HTableMetrics {
112104
}
113105

114106
auto ShouldFinish() -> bool {
115-
auto now = ClockMs();
116-
return now - start_time_ > duration_ms_;
107+
auto now = std::chrono::steady_clock::now();
108+
return std::chrono::duration_cast<std::chrono::milliseconds>(now - start_time_).count() > duration_ms_;
117109
}
118110
};
119111

tools/terrier_bench/terrier.cpp

Lines changed: 11 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -35,24 +35,16 @@
3535
#include "fmt/core.h"
3636
#include "fmt/std.h"
3737

38-
#include <sys/time.h>
39-
40-
auto ClockMs() -> uint64_t {
41-
struct timeval tm;
42-
gettimeofday(&tm, nullptr);
43-
return static_cast<uint64_t>(tm.tv_sec * 1000) + static_cast<uint64_t>(tm.tv_usec / 1000);
44-
}
45-
4638
struct TerrierTotalMetrics {
4739
uint64_t aborted_transfer_txn_cnt_{0};
4840
uint64_t committed_transfer_txn_cnt_{0};
4941
uint64_t aborted_join_txn_cnt_{0};
5042
uint64_t committed_join_txn_cnt_{0};
51-
uint64_t start_time_{0};
43+
std::chrono::steady_clock::time_point start_time_;
5244
uint64_t elapsed_{0};
5345
std::mutex mutex_;
5446

55-
void Begin() { start_time_ = ClockMs(); }
47+
void Begin() { start_time_ = std::chrono::steady_clock::now(); }
5648

5749
void ReportTransfer(uint64_t aborted_cnt, uint64_t committed_cnt) {
5850
std::unique_lock<std::mutex> l(mutex_);
@@ -67,8 +59,8 @@ struct TerrierTotalMetrics {
6759
}
6860

6961
void End() {
70-
auto now = ClockMs();
71-
elapsed_ = now - start_time_;
62+
auto now = std::chrono::steady_clock::now();
63+
elapsed_ = std::chrono::duration_cast<std::chrono::milliseconds>(now - start_time_).count();
7264
}
7365

7466
void Report(uint64_t db_size) {
@@ -93,7 +85,7 @@ struct TerrierTotalMetrics {
9385
};
9486

9587
struct TerrierMetrics {
96-
uint64_t start_time_{0};
88+
std::chrono::steady_clock::time_point start_time_;
9789
uint64_t last_report_at_{0};
9890
uint64_t last_committed_txn_cnt_{0};
9991
uint64_t last_aborted_txn_cnt_{0};
@@ -109,12 +101,12 @@ struct TerrierMetrics {
109101

110102
void TxnCommitted() { committed_txn_cnt_ += 1; }
111103

112-
void Begin() { start_time_ = ClockMs(); }
104+
void Begin() { start_time_ = std::chrono::steady_clock::now(); }
113105

114106
void Report() {
115-
auto now = ClockMs();
116-
auto elapsed = now - start_time_;
117-
if (elapsed - last_report_at_ > 1000) {
107+
auto now = std::chrono::steady_clock::now();
108+
auto elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(now - start_time_).count();
109+
if (elapsed - last_report_at_ >= 1000) {
118110
fmt::print(stderr,
119111
"[{:5.2f}] {}: total_committed_txn={:<8} total_aborted_txn={:<8} throughput={:<8.3f} "
120112
"avg_throughput={:<8.3f}\n",
@@ -127,8 +119,8 @@ struct TerrierMetrics {
127119
}
128120

129121
auto ShouldFinish() -> bool {
130-
auto now = ClockMs();
131-
return now - start_time_ > duration_ms_;
122+
auto now = std::chrono::steady_clock::now();
123+
return std::chrono::duration_cast<std::chrono::milliseconds>(now - start_time_).count() > duration_ms_;
132124
}
133125
};
134126

0 commit comments

Comments
 (0)