forked from falcon-transport/verbsmarks
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy paththroughput_computer.cc
More file actions
121 lines (103 loc) · 4.29 KB
/
Copy paththroughput_computer.cc
File metadata and controls
121 lines (103 loc) · 4.29 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
// Copyright 2024 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "throughput_computer.h"
#include <cstdint>
#include <vector>
#include "absl/log/log.h"
#include "utils.h"
#include "verbsmarks.pb.h"
namespace verbsmarks {
std::vector<proto::ThroughputResult> ThroughputComputer::AddMeasurement(
int64_t timestamp, int64_t bytes_completed) {
std::vector<proto::ThroughputResult> result_in_last_seconds;
if (beginning_of_current_second_ == kFinishedTimestamp) {
LOG(ERROR) << "ThroughputComputer cannot add new measurements after "
"FinishMeasurements has been called.";
return result_in_last_seconds;
}
end_of_measurement_ = timestamp;
if (beginning_of_current_second_ == kNotStartedTimestamp) {
// If this is the first measurement added to this ThroughputCounter, use
// `timestamp` as the start time of the first second.
beginning_of_current_second_ = timestamp;
beginning_of_measurement_ = timestamp;
} else if (timestamp >=
beginning_of_current_second_ + utils::kSecondInNanoseconds) {
// If this new measurement takes us into a new second, set the return value
// to the throughput of the past second(s) and compute average throughput.
do {
int seconds_from_start =
(beginning_of_current_second_ - beginning_of_measurement_) /
utils::kSecondInNanoseconds;
result_in_last_seconds.push_back(utils::MakeThroughputResult(
ops_in_current_second_, bytes_in_current_second_,
seconds_from_start));
AddCurrentSecondToAverage();
beginning_of_current_second_ += utils::kSecondInNanoseconds;
ops_in_current_second_ = 0;
bytes_in_current_second_ = 0;
} while (timestamp >=
beginning_of_current_second_ + utils::kSecondInNanoseconds);
}
++ops_in_current_second_;
bytes_in_current_second_ += bytes_completed;
return result_in_last_seconds;
}
std::vector<proto::ThroughputResult> ThroughputComputer::FinishMeasurements(
int64_t timestamp) {
// If end timestamp is not provided, end_of_measurement_ will be the time of
// the last sample.
if (timestamp != 0) {
end_of_measurement_ = timestamp;
}
std::vector<proto::ThroughputResult> result_in_last_seconds;
if (beginning_of_current_second_ != kFinishedTimestamp) {
// Record stats for all seconds up to the finishing time.
do {
int seconds_from_start =
(beginning_of_current_second_ - beginning_of_measurement_) /
utils::kSecondInNanoseconds;
result_in_last_seconds.push_back(utils::MakeThroughputResult(
ops_in_current_second_, bytes_in_current_second_,
seconds_from_start));
AddCurrentSecondToAverage();
beginning_of_current_second_ += utils::kSecondInNanoseconds;
ops_in_current_second_ = 0;
bytes_in_current_second_ = 0;
} while (timestamp >= beginning_of_current_second_);
beginning_of_current_second_ = kFinishedTimestamp;
}
return result_in_last_seconds;
}
void ThroughputComputer::AddCurrentSecondToAverage() {
total_ops_ += ops_in_current_second_;
total_bytes_ += bytes_in_current_second_;
}
proto::ThroughputResult ThroughputComputer::GetAverageResult() const {
proto::ThroughputResult result;
double duration_nanos = (end_of_measurement_ - beginning_of_measurement_);
double duration_seconds = duration_nanos / utils::kSecondInNanoseconds;
if (duration_seconds == 0) {
return result;
}
double ops_per_second = total_ops_ / duration_seconds;
double bytes_per_second = total_bytes_ / duration_seconds;
double gigabits_per_second = bytes_per_second * 8 / 1e9;
result.set_ops_per_second(ops_per_second);
result.set_bytes_per_second(bytes_per_second);
result.set_gbps(gigabits_per_second);
result.set_seconds_from_start(0);
return result;
}
} // namespace verbsmarks