Skip to content

Commit b9dbe65

Browse files
test: extend simple benchmark for UDP gateway
1 parent 2981269 commit b9dbe65

File tree

1 file changed

+72
-22
lines changed

1 file changed

+72
-22
lines changed

tests/benchmarks/gateways/udp_network_gateway_benchmark.cpp

Lines changed: 72 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -18,24 +18,34 @@
1818
using namespace srsran;
1919

2020
struct bench_params {
21-
unsigned nof_repetitions = 100;
21+
unsigned pdu_len = 1400;
22+
unsigned nof_pdus = 100000;
23+
unsigned slow_inter_rx_us = 500;
2224
};
2325

2426
static void usage(const char* prog, const bench_params& params)
2527
{
26-
fmt::print("Usage: {} [-R repetitions] [-s silent]\n", prog);
27-
fmt::print("\t-R Repetitions [Default {}]\n", params.nof_repetitions);
28+
fmt::print("Usage: {} [-n <nof PDUs>] [-l <PDU len>] [-u <t us>]\n", prog);
29+
fmt::print("\t-l PDU len [Default {}]\n", params.pdu_len);
30+
fmt::print("\t-n Number of PDUs [Default {}]\n", params.nof_pdus);
31+
fmt::print("\t-u Notify large PDU inter arrival time longer than t microseconds [Default {}]\n",
32+
params.slow_inter_rx_us);
2833
fmt::print("\t-h Show this message\n");
2934
}
3035

3136
static void parse_args(int argc, char** argv, bench_params& params)
3237
{
3338
int opt = 0;
34-
while ((opt = getopt(argc, argv, "R:h")) != -1) {
39+
while ((opt = getopt(argc, argv, "l:n:u:h")) != -1) {
3540
switch (opt) {
36-
case 'R':
37-
params.nof_repetitions = std::strtol(optarg, nullptr, 10);
41+
case 'l':
42+
params.pdu_len = std::strtol(optarg, nullptr, 10);
3843
break;
44+
case 'n':
45+
params.nof_pdus = std::strtol(optarg, nullptr, 10);
46+
break;
47+
case 'u':
48+
params.slow_inter_rx_us = std::strtol(optarg, nullptr, 10);
3949
case 'h':
4050
default:
4151
usage(argv[0], params);
@@ -47,19 +57,52 @@ static void parse_args(int argc, char** argv, bench_params& params)
4757
class dummy_network_gateway_data_notifier_with_src_addr : public network_gateway_data_notifier_with_src_addr
4858
{
4959
public:
50-
dummy_network_gateway_data_notifier_with_src_addr() = default;
60+
dummy_network_gateway_data_notifier_with_src_addr(const bench_params& params_) : params(params_) {}
61+
5162
void on_new_pdu(byte_buffer pdu, const sockaddr_storage& src_addr) override
5263
{
5364
rx_bytes += pdu.length();
5465
n_pdus++;
66+
67+
static bool first = true;
68+
auto t_now = std::chrono::high_resolution_clock::now();
69+
if (!first) {
70+
auto duration = std::chrono::duration_cast<std::chrono::microseconds>(t_now - t_last);
71+
if (duration < t_min) {
72+
t_min = duration;
73+
}
74+
if (duration > t_max) {
75+
t_max = duration;
76+
}
77+
t_sum += duration;
78+
if (duration.count() > params.slow_inter_rx_us) {
79+
fmt::print("Long inter Rx interval t={}us at n_pdus={}\n", duration.count(), n_pdus);
80+
}
81+
} else {
82+
first = false;
83+
}
84+
85+
t_last = t_now;
5586
}
5687

5788
unsigned get_rx_bytes() { return rx_bytes; }
5889
unsigned get_n_pdus() { return n_pdus; }
5990

91+
std::chrono::microseconds get_t_min() { return t_min; }
92+
std::chrono::microseconds get_t_max() { return t_max; }
93+
std::chrono::microseconds get_t_sum() { return t_sum; }
94+
6095
private:
96+
const bench_params& params;
97+
6198
unsigned rx_bytes = 0;
6299
unsigned n_pdus = 0;
100+
101+
std::chrono::high_resolution_clock::time_point t_last = std::chrono::high_resolution_clock::now();
102+
std::chrono::microseconds t_min = std::chrono::microseconds::max();
103+
std::chrono::microseconds t_max = std::chrono::microseconds::min();
104+
std::chrono::microseconds t_sum = std::chrono::microseconds::zero();
105+
;
63106
};
64107

65108
byte_buffer make_tx_byte_buffer(uint32_t length)
@@ -71,11 +114,6 @@ byte_buffer make_tx_byte_buffer(uint32_t length)
71114
return pdu;
72115
}
73116

74-
byte_buffer make_default_byte_buffer()
75-
{
76-
return make_tx_byte_buffer(1400);
77-
}
78-
79117
sockaddr_storage to_sockaddr_storage(std::string dest_addr, uint16_t port)
80118
{
81119
in_addr inaddr_v4 = {};
@@ -110,14 +148,14 @@ int main(int argc, char** argv)
110148
udp_network_gateway_config gw1_cfg;
111149
gw1_cfg.bind_address = "127.0.0.1";
112150
gw1_cfg.bind_port = 56701;
113-
gw1_cfg.non_blocking_mode = true;
151+
gw1_cfg.non_blocking_mode = false;
114152

115153
udp_network_gateway_config gw2_cfg;
116154
gw2_cfg.bind_address = "127.0.0.1";
117155
gw2_cfg.bind_port = 56702;
118-
gw2_cfg.non_blocking_mode = true;
156+
gw2_cfg.non_blocking_mode = false;
119157

120-
dummy_network_gateway_data_notifier_with_src_addr gw1_dn, gw2_dn;
158+
dummy_network_gateway_data_notifier_with_src_addr gw1_dn{params}, gw2_dn{params};
121159
std::unique_ptr<udp_network_gateway> gw1, gw2;
122160

123161
gw1 = create_udp_network_gateway({gw1_cfg, gw1_dn});
@@ -135,23 +173,35 @@ int main(int argc, char** argv)
135173

136174
sockaddr_storage gw2_addr = to_sockaddr_storage(gw2_cfg.bind_address, gw2_cfg.bind_port);
137175

138-
byte_buffer pdu = make_default_byte_buffer();
176+
byte_buffer pdu = make_tx_byte_buffer(params.pdu_len);
139177

140178
auto t_start = std::chrono::high_resolution_clock::now();
141179

142-
unsigned N = 100000;
143-
for (unsigned n = 0; n < N; n++) {
180+
unsigned nof_pdus = params.nof_pdus;
181+
for (unsigned n = 0; n < nof_pdus; n++) {
144182
gw1->handle_pdu(pdu, gw2_addr);
145183
}
146184
auto t_end = std::chrono::high_resolution_clock::now();
147185
auto duration = std::chrono::duration_cast<std::chrono::microseconds>(t_end - t_start);
186+
fmt::print("Tx done\n\n");
148187

149188
std::this_thread::sleep_for(std::chrono::milliseconds(250));
150189

151190
fmt::print("Tx time: {} us\n", duration.count());
152-
fmt::print("Tx data rate: {:.2f} Mbit/s\n\n", (double)pdu.length() * N * 8 * 1e-6 / (duration.count() * 1e-6));
153-
fmt::print("Tx PDU rate: {:.2f} PDU/s\n", (double)N / (duration.count() * 1e-6));
191+
fmt::print("Tx data rate: {:.2f} Mbit/s\n", (double)pdu.length() * nof_pdus * 8 * 1e-6 / (duration.count() * 1e-6));
192+
fmt::print("Rx data rate: {:.2f} Mbit/s\n\n",
193+
(double)pdu.length() * gw2_dn.get_n_pdus() * 8 * 1e-6 / (duration.count() * 1e-6));
194+
195+
fmt::print("Tx PDU rate: {:.2f} PDU/s\n", (double)nof_pdus / (duration.count() * 1e-6));
154196
fmt::print("Rx PDU rate: {:.2f} PDU/s\n\n", (double)gw2_dn.get_n_pdus() / (duration.count() * 1e-6));
155-
fmt::print("Tx PDUs total: {:>7}\n", N);
156-
fmt::print("Rx PDUs total: {:>7}\n", gw2_dn.get_n_pdus());
197+
198+
fmt::print("Tx PDUs total: {:>7}\n", nof_pdus);
199+
fmt::print("Rx PDUs total: {:>7} ({:.2f}% lost)\n\n",
200+
gw2_dn.get_n_pdus(),
201+
(1 - ((double)gw2_dn.get_n_pdus() / nof_pdus)) * 100);
202+
203+
fmt::print("PDU inter arrival time (min/avg/max) [us]: {}/{}/{}\n",
204+
gw2_dn.get_t_min().count(),
205+
gw2_dn.get_t_sum().count() / gw2_dn.get_n_pdus(),
206+
gw2_dn.get_t_max().count());
157207
}

0 commit comments

Comments
 (0)