1818using namespace srsran ;
1919
2020struct 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
2426static 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
3136static 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)
4757class dummy_network_gateway_data_notifier_with_src_addr : public network_gateway_data_notifier_with_src_addr
4858{
4959public:
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+
6095private:
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
65108byte_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-
79117sockaddr_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