15#include <odp/helper/odph_api.h>
17#include <bench_common.h>
18#include <export_results.h>
27#define TEST_BUF_SIZE 1024
30#define TEST_UAREA_SIZE 8
33#define TEST_REPEAT_COUNT 1000
36#define TEST_ROUNDS 100u
39#define TEST_MAX_BURST 64
42#define TEST_DEF_BURST 8
45#define TEST_MAX_BENCH 40
48#define NO_PATH(file_name) (strrchr((file_name), '/') ? \
49 strrchr((file_name), '/') + 1 : (file_name))
51#define BENCH_INFO(run_fn, init_fn, term_fn, alt_name) \
52 {.name = #run_fn, .run = run_fn, .init = init_fn, .term = term_fn, .desc = alt_name}
54#define BENCH_INFO_COND(run_fn, init_fn, term_fn, alt_name, cond_fn) \
55 {.name = #run_fn, .run = run_fn, .init = init_fn, .term = term_fn, .desc = alt_name, \
58#define BENCH_INFO_TM(run_fn, init_fn, term_fn, cond_fn) \
59 {.name = #run_fn, .run = run_fn, .init = init_fn, .term = term_fn, .cond = cond_fn,\
102 int (*suite_fn)(
void *args);
104 int (*export_fn)(
void *data);
114 uint32_t max_flow_id;
116 odp_buffer_t buf_tbl[TEST_REPEAT_COUNT * TEST_MAX_BURST];
118 odp_event_t event_tbl[TEST_REPEAT_COUNT * TEST_MAX_BURST];
120 void *ptr_tbl[TEST_REPEAT_COUNT];
132 double b[TEST_MAX_BENCH];
134 bench_tm_result_t t[TEST_MAX_BENCH];
139static args_t *gbl_args;
143 if (gbl_args == NULL)
148static void allocate_test_buffers(
odp_buffer_t buf[],
int num)
152 while (num_buf < num) {
157 ODPH_ABORT(
"Allocating test buffers failed\n");
163static void create_buffers(
void)
165 allocate_test_buffers(gbl_args->buf_tbl, TEST_REPEAT_COUNT);
168static void create_buffers_multi(
void)
170 allocate_test_buffers(gbl_args->buf_tbl, TEST_REPEAT_COUNT * gbl_args->appl.burst_size);
173static void create_events(
void)
177 allocate_test_buffers(gbl_args->buf_tbl, TEST_REPEAT_COUNT);
179 for (
int i = 0; i < TEST_REPEAT_COUNT; i++)
183static void create_events_multi(
void)
187 allocate_test_buffers(gbl_args->buf_tbl,
188 TEST_REPEAT_COUNT * gbl_args->appl.burst_size);
190 for (
int i = 0; i < TEST_REPEAT_COUNT * gbl_args->appl.burst_size; i++)
194static void free_buffers(
void)
199static void free_buffers_multi(
void)
204static int check_uarea(
void)
206 return !!gbl_args->uarea_size;
209static int check_flow_aware(
void)
211 return !!gbl_args->max_flow_id;
214static int buffer_from_event(
void)
220 for (i = 0; i < TEST_REPEAT_COUNT; i++)
226static int buffer_from_event_tm(bench_tm_result_t *res,
int repeat_count)
231 const uint8_t id1 = bench_tm_func_register(res,
"odp_buffer_from_event()");
232 bench_tm_stamp_t s1, s2;
234 for (i = 0; i < repeat_count; i++) {
235 bench_tm_now(res, &s1);
237 bench_tm_now(res, &s2);
238 bench_tm_func_record(&s2, &s1, res, id1);
244static int buffer_from_event_multi(
void)
248 int burst_size = gbl_args->appl.burst_size;
251 for (i = 0; i < TEST_REPEAT_COUNT; i++)
253 &event_tbl[i * burst_size], burst_size);
258static int buffer_from_event_multi_tm(bench_tm_result_t *res,
int repeat_count)
262 int burst_size = gbl_args->appl.burst_size;
264 const uint8_t id1 = bench_tm_func_register(res,
"odp_buffer_from_event_multi()");
265 bench_tm_stamp_t s1, s2;
267 for (i = 0; i < repeat_count; i++) {
268 bench_tm_now(res, &s1);
270 &event_tbl[i * burst_size], burst_size);
271 bench_tm_now(res, &s2);
272 bench_tm_func_record(&s2, &s1, res, id1);
278static int buffer_to_event(
void)
284 for (i = 0; i < TEST_REPEAT_COUNT; i++)
290static int buffer_to_event_tm(bench_tm_result_t *res,
int repeat_count)
295 const uint8_t id1 = bench_tm_func_register(res,
"odp_buffer_to_event()");
296 bench_tm_stamp_t s1, s2;
298 for (i = 0; i < repeat_count; i++) {
299 bench_tm_now(res, &s1);
301 bench_tm_now(res, &s2);
302 bench_tm_func_record(&s2, &s1, res, id1);
308static int buffer_to_event_multi(
void)
312 int burst_size = gbl_args->appl.burst_size;
315 for (i = 0; i < TEST_REPEAT_COUNT; i++)
317 &event_tbl[i * burst_size], burst_size);
322static int buffer_to_event_multi_tm(bench_tm_result_t *res,
int repeat_count)
326 int burst_size = gbl_args->appl.burst_size;
328 const uint8_t id1 = bench_tm_func_register(res,
"odp_buffer_to_event_multi()");
329 bench_tm_stamp_t s1, s2;
331 for (i = 0; i < repeat_count; i++) {
332 bench_tm_now(res, &s1);
334 &event_tbl[i * burst_size], burst_size);
335 bench_tm_now(res, &s2);
336 bench_tm_func_record(&s2, &s1, res, id1);
342static int buffer_addr(
void)
345 void **ptr_tbl = gbl_args->ptr_tbl;
348 for (i = 0; i < TEST_REPEAT_COUNT; i++)
354static int buffer_addr_tm(bench_tm_result_t *res,
int repeat_count)
357 void **ptr_tbl = gbl_args->ptr_tbl;
359 const uint8_t id1 = bench_tm_func_register(res,
"odp_buffer_addr()");
360 bench_tm_stamp_t s1, s2;
362 for (i = 0; i < repeat_count; i++) {
363 bench_tm_now(res, &s1);
365 bench_tm_now(res, &s2);
366 bench_tm_func_record(&s2, &s1, res, id1);
372static int buffer_size(
void)
377 for (
int i = 0; i < TEST_REPEAT_COUNT; i++)
383static int buffer_size_tm(bench_tm_result_t *res,
int repeat_count)
387 const uint8_t id1 = bench_tm_func_register(res,
"odp_buffer_size()");
388 bench_tm_stamp_t s1, s2;
390 for (
int i = 0; i < repeat_count; i++) {
391 bench_tm_now(res, &s1);
393 bench_tm_now(res, &s2);
394 bench_tm_func_record(&s2, &s1, res, id1);
400static int buffer_user_area(
void)
403 void **ptr_tbl = gbl_args->ptr_tbl;
406 for (i = 0; i < TEST_REPEAT_COUNT; i++)
412static int buffer_user_area_tm(bench_tm_result_t *res,
int repeat_count)
415 void **ptr_tbl = gbl_args->ptr_tbl;
417 const uint8_t id1 = bench_tm_func_register(res,
"odp_buffer_user_area()");
418 bench_tm_stamp_t s1, s2;
420 for (i = 0; i < repeat_count; i++) {
421 bench_tm_now(res, &s1);
423 bench_tm_now(res, &s2);
424 bench_tm_func_record(&s2, &s1, res, id1);
430static int buffer_pool(
void)
436 for (i = 0; i < TEST_REPEAT_COUNT; i++)
442static int buffer_pool_tm(bench_tm_result_t *res,
int repeat_count)
447 const uint8_t id1 = bench_tm_func_register(res,
"odp_buffer_pool()");
448 bench_tm_stamp_t s1, s2;
450 for (i = 0; i < repeat_count; i++) {
451 bench_tm_now(res, &s1);
453 bench_tm_now(res, &s2);
454 bench_tm_func_record(&s2, &s1, res, id1);
460static int buffer_alloc(
void)
466 for (i = 0; i < TEST_REPEAT_COUNT; i++)
472static int buffer_alloc_tm(bench_tm_result_t *res,
int repeat_count)
477 const uint8_t id1 = bench_tm_func_register(res,
"odp_buffer_alloc()");
478 bench_tm_stamp_t s1, s2;
480 for (i = 0; i < repeat_count; i++) {
481 bench_tm_now(res, &s1);
483 bench_tm_now(res, &s2);
484 bench_tm_func_record(&s2, &s1, res, id1);
490static int buffer_alloc_multi(
void)
494 int burst_size = gbl_args->appl.burst_size;
497 for (
int i = 0; i < TEST_REPEAT_COUNT; i++)
503static int buffer_alloc_multi_tm(bench_tm_result_t *res,
int repeat_count)
507 int burst_size = gbl_args->appl.burst_size;
509 const uint8_t id1 = bench_tm_func_register(res,
"odp_buffer_alloc_multi()");
510 bench_tm_stamp_t s1, s2;
512 for (
int i = 0; i < repeat_count; i++) {
513 bench_tm_now(res, &s1);
515 bench_tm_now(res, &s2);
516 bench_tm_func_record(&s2, &s1, res, id1);
522static int buffer_free(
void)
527 for (i = 0; i < TEST_REPEAT_COUNT; i++)
533static int buffer_free_tm(bench_tm_result_t *res,
int repeat_count)
537 const uint8_t id1 = bench_tm_func_register(res,
"odp_buffer_free()");
538 bench_tm_stamp_t s1, s2;
540 for (i = 0; i < repeat_count; i++) {
541 bench_tm_now(res, &s1);
543 bench_tm_now(res, &s2);
544 bench_tm_func_record(&s2, &s1, res, id1);
550static int buffer_free_multi(
void)
553 int burst_size = gbl_args->appl.burst_size;
556 for (i = 0; i < TEST_REPEAT_COUNT; i++)
562static int buffer_free_multi_tm(bench_tm_result_t *res,
int repeat_count)
565 int burst_size = gbl_args->appl.burst_size;
567 const uint8_t id1 = bench_tm_func_register(res,
"odp_buffer_free_multi()");
568 bench_tm_stamp_t s1, s2;
570 for (i = 0; i < repeat_count; i++) {
571 bench_tm_now(res, &s1);
573 bench_tm_now(res, &s2);
574 bench_tm_func_record(&s2, &s1, res, id1);
580static int buffer_alloc_free(
void)
585 for (i = 0; i < TEST_REPEAT_COUNT; i++) {
596static int buffer_alloc_free_tm(bench_tm_result_t *res,
int repeat_count)
600 const uint8_t id1 = bench_tm_func_register(res,
"odp_buffer_alloc()/_free()");
601 bench_tm_stamp_t s1, s2;
603 for (i = 0; i < repeat_count; i++) {
604 bench_tm_now(res, &s1);
610 bench_tm_now(res, &s2);
611 bench_tm_func_record(&s2, &s1, res, id1);
617static int buffer_alloc_free_multi(
void)
621 int burst_size = gbl_args->appl.burst_size;
624 for (i = 0; i < TEST_REPEAT_COUNT; i++) {
635static int buffer_alloc_free_multi_tm(bench_tm_result_t *res,
int repeat_count)
639 int burst_size = gbl_args->appl.burst_size;
641 const uint8_t id1 = bench_tm_func_register(res,
"odp_buffer_alloc_multi()/_free_multi()");
642 bench_tm_stamp_t s1, s2;
644 for (i = 0; i < repeat_count; i++) {
645 bench_tm_now(res, &s1);
648 ODPH_ASSERT(num >= 1);
651 bench_tm_now(res, &s2);
652 bench_tm_func_record(&s2, &s1, res, id1);
658static int buffer_is_valid(
void)
663 for (
int i = 0; i < TEST_REPEAT_COUNT; i++)
669static int buffer_is_valid_tm(bench_tm_result_t *res,
int repeat_count)
673 const uint8_t id1 = bench_tm_func_register(res,
"odp_buffer_is_valid()");
674 bench_tm_stamp_t s1, s2;
676 for (
int i = 0; i < repeat_count; i++) {
677 bench_tm_now(res, &s1);
679 bench_tm_now(res, &s2);
680 bench_tm_func_record(&s2, &s1, res, id1);
686static int event_type(
void)
692 for (i = 0; i < TEST_REPEAT_COUNT; i++)
698static int event_type_tm(bench_tm_result_t *res,
int repeat_count)
703 const uint8_t id1 = bench_tm_func_register(res,
"odp_event_type()");
704 bench_tm_stamp_t s1, s2;
706 for (i = 0; i < repeat_count; i++) {
707 bench_tm_now(res, &s1);
709 bench_tm_now(res, &s2);
710 bench_tm_func_record(&s2, &s1, res, id1);
716static int event_subtype(
void)
722 for (i = 0; i < TEST_REPEAT_COUNT; i++)
728static int event_subtype_tm(bench_tm_result_t *res,
int repeat_count)
733 const uint8_t id1 = bench_tm_func_register(res,
"odp_event_subtype()");
734 bench_tm_stamp_t s1, s2;
736 for (i = 0; i < repeat_count; i++) {
737 bench_tm_now(res, &s1);
739 bench_tm_now(res, &s2);
740 bench_tm_func_record(&s2, &s1, res, id1);
746static int event_types(
void)
753 for (i = 0; i < TEST_REPEAT_COUNT; i++)
754 event_type_tbl[i] =
odp_event_types(event_tbl[i], &event_subtype_tbl[i]);
759static int event_types_tm(bench_tm_result_t *res,
int repeat_count)
765 const uint8_t id1 = bench_tm_func_register(res,
"odp_event_types()");
766 bench_tm_stamp_t s1, s2;
768 for (i = 0; i < repeat_count; i++) {
769 bench_tm_now(res, &s1);
770 event_type_tbl[i] =
odp_event_types(event_tbl[i], &event_subtype_tbl[i]);
771 bench_tm_now(res, &s2);
772 bench_tm_func_record(&s2, &s1, res, id1);
778static int event_types_multi(
void)
783 int burst_size = gbl_args->appl.burst_size;
786 for (i = 0; i < TEST_REPEAT_COUNT; i++)
788 &event_type_tbl[i * burst_size],
789 &event_subtype_tbl[i * burst_size], burst_size);
794static int event_types_multi_tm(bench_tm_result_t *res,
int repeat_count)
799 int burst_size = gbl_args->appl.burst_size;
801 const uint8_t id1 = bench_tm_func_register(res,
"odp_event_types_multi()");
802 bench_tm_stamp_t s1, s2;
804 for (i = 0; i < repeat_count; i++) {
805 bench_tm_now(res, &s1);
807 &event_type_tbl[i * burst_size],
808 &event_subtype_tbl[i * burst_size], burst_size);
809 bench_tm_now(res, &s2);
810 bench_tm_func_record(&s2, &s1, res, id1);
816static int event_types_multi_no_sub(
void)
820 int burst_size = gbl_args->appl.burst_size;
823 for (i = 0; i < TEST_REPEAT_COUNT; i++)
825 &event_type_tbl[i * burst_size], NULL, burst_size);
830static int event_types_multi_no_sub_tm(bench_tm_result_t *res,
int repeat_count)
834 int burst_size = gbl_args->appl.burst_size;
836 const uint8_t id1 = bench_tm_func_register(res,
"odp_event_types_multi()");
837 bench_tm_stamp_t s1, s2;
839 for (i = 0; i < repeat_count; i++) {
840 bench_tm_now(res, &s1);
842 &event_type_tbl[i * burst_size], NULL, burst_size);
843 bench_tm_now(res, &s2);
844 bench_tm_func_record(&s2, &s1, res, id1);
850static int event_type_multi(
void)
854 int burst_size = gbl_args->appl.burst_size;
857 for (
int i = 0; i < TEST_REPEAT_COUNT; i++)
864static int event_type_multi_tm(bench_tm_result_t *res,
int repeat_count)
868 int burst_size = gbl_args->appl.burst_size;
870 const uint8_t id1 = bench_tm_func_register(res,
"odp_event_type_multi()");
871 bench_tm_stamp_t s1, s2;
873 for (
int i = 0; i < repeat_count; i++) {
874 bench_tm_now(res, &s1);
877 bench_tm_now(res, &s2);
878 bench_tm_func_record(&s2, &s1, res, id1);
884static int event_pool(
void)
890 for (i = 0; i < TEST_REPEAT_COUNT; i++)
896static int event_pool_tm(bench_tm_result_t *res,
int repeat_count)
901 const uint8_t id1 = bench_tm_func_register(res,
"odp_event_pool()");
902 bench_tm_stamp_t s1, s2;
904 for (i = 0; i < repeat_count; i++) {
905 bench_tm_now(res, &s1);
907 bench_tm_now(res, &s2);
908 bench_tm_func_record(&s2, &s1, res, id1);
914static int event_user_area(
void)
917 void **ptr_tbl = gbl_args->ptr_tbl;
920 for (i = 0; i < TEST_REPEAT_COUNT; i++)
926static int event_user_area_tm(bench_tm_result_t *res,
int repeat_count)
929 void **ptr_tbl = gbl_args->ptr_tbl;
931 const uint8_t id1 = bench_tm_func_register(res,
"odp_event_user_area()");
932 bench_tm_stamp_t s1, s2;
934 for (i = 0; i < repeat_count; i++) {
935 bench_tm_now(res, &s1);
937 bench_tm_now(res, &s2);
938 bench_tm_func_record(&s2, &s1, res, id1);
944static int event_user_area_and_flag(
void)
947 void **ptr_tbl = gbl_args->ptr_tbl;
951 for (
int i = 0; i < TEST_REPEAT_COUNT; i++) {
959static int event_user_area_and_flag_tm(bench_tm_result_t *res,
int repeat_count)
962 void **ptr_tbl = gbl_args->ptr_tbl;
965 const uint8_t id1 = bench_tm_func_register(res,
"odp_event_user_area_and_flag()");
966 bench_tm_stamp_t s1, s2;
968 for (
int i = 0; i < repeat_count; i++) {
969 bench_tm_now(res, &s1);
971 bench_tm_now(res, &s2);
972 bench_tm_func_record(&s2, &s1, res, id1);
979static int event_is_valid(
void)
985 for (
int i = 0; i < TEST_REPEAT_COUNT; i++)
991static int event_is_valid_tm(bench_tm_result_t *res,
int repeat_count)
995 const uint8_t id1 = bench_tm_func_register(res,
"odp_event_is_valid()");
996 bench_tm_stamp_t s1, s2;
998 for (
int i = 0; i < repeat_count; i++) {
999 bench_tm_now(res, &s1);
1001 bench_tm_now(res, &s2);
1002 bench_tm_func_record(&s2, &s1, res, id1);
1008static int event_free(
void)
1014 for (i = 0; i < TEST_REPEAT_COUNT; i++)
1020static int event_free_tm(bench_tm_result_t *res,
int repeat_count)
1024 const uint8_t id1 = bench_tm_func_register(res,
"odp_event_free()");
1025 bench_tm_stamp_t s1, s2;
1027 for (i = 0; i < repeat_count; i++) {
1028 bench_tm_now(res, &s1);
1030 bench_tm_now(res, &s2);
1031 bench_tm_func_record(&s2, &s1, res, id1);
1037static int event_free_multi(
void)
1040 int burst_size = gbl_args->appl.burst_size;
1043 for (i = 0; i < TEST_REPEAT_COUNT; i++)
1049static int event_free_multi_tm(bench_tm_result_t *res,
int repeat_count)
1052 int burst_size = gbl_args->appl.burst_size;
1054 const uint8_t id1 = bench_tm_func_register(res,
"odp_event_free_multi()");
1055 bench_tm_stamp_t s1, s2;
1057 for (i = 0; i < repeat_count; i++) {
1058 bench_tm_now(res, &s1);
1060 bench_tm_now(res, &s2);
1061 bench_tm_func_record(&s2, &s1, res, id1);
1067static int event_free_sp(
void)
1070 int burst_size = gbl_args->appl.burst_size;
1073 for (i = 0; i < TEST_REPEAT_COUNT; i++)
1079static int event_free_sp_tm(bench_tm_result_t *res,
int repeat_count)
1082 int burst_size = gbl_args->appl.burst_size;
1084 const uint8_t id1 = bench_tm_func_register(res,
"odp_event_free_sp()");
1085 bench_tm_stamp_t s1, s2;
1087 for (i = 0; i < repeat_count; i++) {
1088 bench_tm_now(res, &s1);
1090 bench_tm_now(res, &s2);
1091 bench_tm_func_record(&s2, &s1, res, id1);
1097static int event_flow_id(
void)
1102 for (
int i = 0; i < TEST_REPEAT_COUNT; i++)
1108static int event_flow_id_tm(bench_tm_result_t *res,
int repeat_count)
1112 const uint8_t id1 = bench_tm_func_register(res,
"odp_event_flow_id()");
1113 bench_tm_stamp_t s1, s2;
1115 for (
int i = 0; i < repeat_count; i++) {
1116 bench_tm_now(res, &s1);
1118 bench_tm_now(res, &s2);
1119 bench_tm_func_record(&s2, &s1, res, id1);
1125static int event_flow_id_set(
void)
1130 for (i = 0; i < TEST_REPEAT_COUNT; i++)
1136static int event_flow_id_set_tm(bench_tm_result_t *res,
int repeat_count)
1140 const uint8_t id1 = bench_tm_func_register(res,
"odp_event_flow_id_set()");
1141 bench_tm_stamp_t s1, s2;
1143 for (i = 0; i < repeat_count; i++) {
1144 bench_tm_now(res, &s1);
1146 bench_tm_now(res, &s2);
1147 bench_tm_func_record(&s2, &s1, res, id1);
1156static void usage(
char *progname)
1159 "OpenDataPlane Buffer/Event API microbenchmarks.\n"
1161 "Usage: %s OPTIONS\n"
1164 "Optional OPTIONS:\n"
1165 " -b, --burst <num> Test burst size.\n"
1166 " -c, --cache_size <num> Pool cache size.\n"
1167 " -i, --index <idx> Benchmark index to run indefinitely.\n"
1168 " -r, --rounds <num> Run each test case 'num' times (default %u).\n"
1169 " -t, --time <opt> Time measurement. 0: measure CPU cycles (default), 1: measure time\n"
1170 " -m, --mode <mode> Measurement mode. 0: measure throughput, track average execution\n"
1171 " time (default), 1: measure latency, track function minimum and\n"
1172 " maximum in addition to average execution time.\n"
1173 " -h, --help Display help and exit.\n\n"
1174 "\n", NO_PATH(progname), NO_PATH(progname), TEST_ROUNDS);
1184static void parse_args(
int argc,
char *argv[], appl_args_t *appl_args)
1187 static const struct option longopts[] = {
1188 {
"burst", required_argument, NULL,
'b'},
1189 {
"cache_size", required_argument, NULL,
'c'},
1190 {
"index", required_argument, NULL,
'i'},
1191 {
"rounds", required_argument, NULL,
'r'},
1192 {
"time", required_argument, NULL,
't'},
1193 {
"mode", required_argument, NULL,
'm'},
1194 {
"help", no_argument, NULL,
'h'},
1198 static const char *shortopts =
"c:b:i:r:t:m:h";
1200 appl_args->bench_idx = 0;
1201 appl_args->burst_size = TEST_DEF_BURST;
1202 appl_args->cache_size = -1;
1203 appl_args->rounds = TEST_ROUNDS;
1204 appl_args->time = 0;
1205 appl_args->mode = M_TPUT;
1208 opt = getopt_long(argc, argv, shortopts, longopts, NULL);
1215 appl_args->cache_size = atoi(optarg);
1218 appl_args->burst_size = atoi(optarg);
1225 appl_args->bench_idx = atoi(optarg);
1228 appl_args->rounds = atoi(optarg);
1231 appl_args->time = atoi(optarg);
1234 appl_args->mode = atoi(optarg);
1241 if (appl_args->burst_size < 1 ||
1242 appl_args->burst_size > TEST_MAX_BURST) {
1243 printf(
"Invalid burst size (max %d)\n", TEST_MAX_BURST);
1247 if (appl_args->rounds < 1) {
1248 printf(
"Invalid number test rounds: %d\n", appl_args->rounds);
1252 if (appl_args->mode != M_TPUT && appl_args->mode != M_LATENCY) {
1253 printf(
"Invalid measurement mode: %d\n", appl_args->mode);
1263static void print_info(
void)
1268 "odp_bench_buffer options\n"
1269 "------------------------\n");
1271 printf(
"Burst size: %d\n", gbl_args->appl.burst_size);
1272 printf(
"Buffer size: %d\n", gbl_args->buf_size);
1273 printf(
"CPU mask: %s\n", gbl_args->cpumask_str);
1274 if (gbl_args->appl.cache_size < 0)
1275 printf(
"Pool cache size: default\n");
1277 printf(
"Pool cache size: %d\n", gbl_args->appl.cache_size);
1278 printf(
"Measurement unit: %s\n", gbl_args->appl.time ?
"nsec" :
"CPU cycles");
1279 printf(
"Test rounds: %u\n", gbl_args->appl.rounds);
1280 printf(
"Measurement mode: %s\n", gbl_args->appl.mode == M_TPUT ?
"throughput" :
"latency");
1284static int bench_buffer_tm_export(
void *data)
1286 args_t *gbl_args = data;
1287 bench_tm_result_t *res;
1290 const char *unit = gbl_args->appl.time ?
"nsec" :
"cpu cycles";
1292 if (test_common_write(
"function name,min %s per function call,"
1293 "average %s per function call,"
1294 "max %s per function call\n", unit, unit, unit)) {
1299 for (uint32_t i = 0; i < gbl_args->suite.t.num_bench; i++) {
1300 res = &gbl_args->suite.t.result[i];
1302 for (
int j = 0; j < res->num; j++) {
1303 num = res->func[j].num ? res->func[j].num : 1;
1304 if (test_common_write(
"%s,%" PRIu64
",%" PRIu64
",%" PRIu64
"\n",
1306 bench_tm_to_u64(res, &res->func[j].min),
1307 bench_tm_to_u64(res, &res->func[j].tot) / num,
1308 bench_tm_to_u64(res, &res->func[j].max))) {
1316 test_common_write_term();
1321static int bench_buffer_export(
void *data)
1323 args_t *gbl_args = data;
1326 if (test_common_write(
"%s", gbl_args->appl.time ?
1327 "function name,average nsec per function call\n" :
1328 "function name,average cpu cycles per function call\n")) {
1333 for (
int i = 0; i < gbl_args->suite.b.num_bench; i++) {
1334 if (test_common_write(
"odp_%s,%f\n", gbl_args->suite.b.bench[i].desc != NULL ?
1335 gbl_args->suite.b.bench[i].desc :
1336 gbl_args->suite.b.bench[i].name,
1337 gbl_args->suite.b.result[i])) {
1344 test_common_write_term();
1352bench_info_t test_suite[] = {
1353 BENCH_INFO(buffer_from_event, create_events, free_buffers, NULL),
1354 BENCH_INFO(buffer_from_event_multi, create_events_multi, free_buffers_multi, NULL),
1355 BENCH_INFO(buffer_to_event, create_buffers, free_buffers, NULL),
1356 BENCH_INFO(buffer_to_event_multi, create_buffers_multi, free_buffers_multi, NULL),
1357 BENCH_INFO(buffer_addr, create_buffers, free_buffers, NULL),
1358 BENCH_INFO(buffer_size, create_buffers, free_buffers, NULL),
1359 BENCH_INFO_COND(buffer_user_area, create_buffers, free_buffers, NULL, check_uarea),
1360 BENCH_INFO(buffer_pool, create_buffers, free_buffers, NULL),
1361 BENCH_INFO(buffer_alloc, NULL, free_buffers, NULL),
1362 BENCH_INFO(buffer_alloc_multi, NULL, free_buffers_multi, NULL),
1363 BENCH_INFO(buffer_free, create_buffers, NULL, NULL),
1364 BENCH_INFO(buffer_free_multi, create_buffers_multi, NULL, NULL),
1365 BENCH_INFO(buffer_alloc_free, NULL, NULL, NULL),
1366 BENCH_INFO(buffer_alloc_free_multi, NULL, NULL, NULL),
1367 BENCH_INFO(buffer_is_valid, create_buffers, free_buffers, NULL),
1368 BENCH_INFO(event_type, create_events, free_buffers, NULL),
1369 BENCH_INFO(event_subtype, create_events, free_buffers, NULL),
1370 BENCH_INFO(event_types, create_events, free_buffers, NULL),
1371 BENCH_INFO(event_types_multi, create_events_multi, free_buffers_multi, NULL),
1372 BENCH_INFO(event_types_multi_no_sub, create_events_multi, free_buffers_multi,
1373 "event_types_multi (no sub)"),
1374 BENCH_INFO(event_type_multi, create_events_multi, free_buffers_multi, NULL),
1375 BENCH_INFO(event_pool, create_events, free_buffers, NULL),
1376 BENCH_INFO_COND(event_user_area, create_events, free_buffers, NULL, check_uarea),
1377 BENCH_INFO_COND(event_user_area_and_flag, create_events, free_buffers, NULL, check_uarea),
1378 BENCH_INFO(event_is_valid, create_events, free_buffers, NULL),
1379 BENCH_INFO(event_free, create_events, NULL, NULL),
1380 BENCH_INFO(event_free_multi, create_events_multi, NULL, NULL),
1381 BENCH_INFO(event_free_sp, create_events_multi, NULL, NULL),
1382 BENCH_INFO_COND(event_flow_id, create_events, free_buffers, NULL, check_flow_aware),
1383 BENCH_INFO_COND(event_flow_id_set, create_events, free_buffers, NULL, check_flow_aware),
1387 "Result array is too small to hold all the results");
1392bench_tm_info_t test_suite_tm[] = {
1393 BENCH_INFO_TM(buffer_from_event_tm, create_events, free_buffers, NULL),
1394 BENCH_INFO_TM(buffer_from_event_multi_tm, create_events_multi, free_buffers_multi, NULL),
1395 BENCH_INFO_TM(buffer_to_event_tm, create_buffers, free_buffers, NULL),
1396 BENCH_INFO_TM(buffer_to_event_multi_tm, create_buffers_multi, free_buffers_multi, NULL),
1397 BENCH_INFO_TM(buffer_addr_tm, create_buffers, free_buffers, NULL),
1398 BENCH_INFO_TM(buffer_size_tm, create_buffers, free_buffers, NULL),
1399 BENCH_INFO_TM(buffer_user_area_tm, create_buffers, free_buffers, check_uarea),
1400 BENCH_INFO_TM(buffer_pool_tm, create_buffers, free_buffers, NULL),
1401 BENCH_INFO_TM(buffer_alloc_tm, NULL, free_buffers, NULL),
1402 BENCH_INFO_TM(buffer_alloc_multi_tm, NULL, free_buffers_multi, NULL),
1403 BENCH_INFO_TM(buffer_free_tm, create_buffers, NULL, NULL),
1404 BENCH_INFO_TM(buffer_free_multi_tm, create_buffers_multi, NULL, NULL),
1405 BENCH_INFO_TM(buffer_alloc_free_tm, NULL, NULL, NULL),
1406 BENCH_INFO_TM(buffer_alloc_free_multi_tm, NULL, NULL, NULL),
1407 BENCH_INFO_TM(buffer_is_valid_tm, create_buffers, free_buffers, NULL),
1408 BENCH_INFO_TM(event_type_tm, create_events, free_buffers, NULL),
1409 BENCH_INFO_TM(event_subtype_tm, create_events, free_buffers, NULL),
1410 BENCH_INFO_TM(event_types_tm, create_events, free_buffers, NULL),
1411 BENCH_INFO_TM(event_types_multi_tm, create_events_multi, free_buffers_multi, NULL),
1412 BENCH_INFO_TM(event_types_multi_no_sub_tm, create_events_multi, free_buffers_multi, NULL),
1413 BENCH_INFO_TM(event_type_multi_tm, create_events_multi, free_buffers_multi, NULL),
1414 BENCH_INFO_TM(event_pool_tm, create_events, free_buffers, NULL),
1415 BENCH_INFO_TM(event_user_area_tm, create_events, free_buffers, check_uarea),
1416 BENCH_INFO_TM(event_user_area_and_flag_tm, create_events, free_buffers, check_uarea),
1417 BENCH_INFO_TM(event_is_valid_tm, create_events, free_buffers, NULL),
1418 BENCH_INFO_TM(event_free_tm, create_events, NULL, NULL),
1419 BENCH_INFO_TM(event_free_multi_tm, create_events_multi, NULL, NULL),
1420 BENCH_INFO_TM(event_free_sp_tm, create_events_multi, NULL, NULL),
1421 BENCH_INFO_TM(event_flow_id_tm, create_events, free_buffers, check_flow_aware),
1422 BENCH_INFO_TM(event_flow_id_set_tm, create_events, free_buffers, check_flow_aware),
1426 "Result array is too small to hold all the results");
1428static void init_suite(args_t *gbl_args,
odp_bool_t is_export)
1430 if (gbl_args->appl.mode == M_LATENCY) {
1431 bench_tm_suite_init(&gbl_args->suite.t);
1432 gbl_args->suite.t.bench = test_suite_tm;
1433 gbl_args->suite.t.num_bench = ODPH_ARRAY_SIZE(test_suite_tm);
1434 gbl_args->suite.t.rounds = TEST_REPEAT_COUNT;
1435 gbl_args->suite.t.bench_idx = gbl_args->appl.bench_idx;
1436 gbl_args->suite.t.measure_time = !!gbl_args->appl.time;
1437 gbl_args->suite.exit = &gbl_args->suite.t.exit_worker;
1438 gbl_args->suite.retval = &gbl_args->suite.t.retval;
1439 gbl_args->suite.args = &gbl_args->suite.t;
1440 gbl_args->suite.suite_fn = bench_tm_run;
1441 gbl_args->suite.export_fn = bench_buffer_tm_export;
1444 gbl_args->suite.t.result = gbl_args->result.t;
1446 bench_suite_init(&gbl_args->suite.b);
1447 gbl_args->suite.b.bench = test_suite;
1448 gbl_args->suite.b.num_bench = ODPH_ARRAY_SIZE(test_suite);
1449 gbl_args->suite.b.indef_idx = gbl_args->appl.bench_idx;
1450 gbl_args->suite.b.rounds = gbl_args->appl.rounds;
1451 gbl_args->suite.b.repeat_count = TEST_REPEAT_COUNT;
1452 gbl_args->suite.b.measure_time = !!gbl_args->appl.time;
1453 gbl_args->suite.exit = &gbl_args->suite.b.exit_worker;
1454 gbl_args->suite.retval = &gbl_args->suite.b.retval;
1455 gbl_args->suite.args = &gbl_args->suite.b;
1456 gbl_args->suite.suite_fn = bench_run;
1457 gbl_args->suite.export_fn = bench_buffer_export;
1460 gbl_args->suite.b.result = gbl_args->result.b;
1467int main(
int argc,
char *argv[])
1469 odph_helper_options_t helper_options;
1470 test_common_options_t common_options;
1471 odph_thread_t worker_thread;
1472 odph_thread_common_param_t thr_common;
1473 odph_thread_param_t thr_param;
1486 argc = odph_parse_options(argc, argv);
1487 if (odph_options(&helper_options)) {
1488 ODPH_ERR(
"Error: reading ODP helper options failed\n");
1492 argc = test_common_parse_options(argc, argv);
1493 if (test_common_options(&common_options)) {
1494 ODPH_ERR(
"Error: reading test options failed\n");
1499 init_param.
mem_model = helper_options.mem_model;
1503 ODPH_ERR(
"Error: ODP global init failed\n");
1509 ODPH_ERR(
"Error: ODP local init failed\n");
1514 shm =
odp_shm_reserve(
"shm_args",
sizeof(args_t), ODP_CACHE_LINE_SIZE, 0);
1516 ODPH_ERR(
"Error: shared mem reserve failed\n");
1521 if (gbl_args == NULL) {
1522 ODPH_ERR(
"Error: shared mem alloc failed\n");
1526 memset(gbl_args, 0,
sizeof(args_t));
1529 parse_args(argc, argv, &gbl_args->appl);
1530 init_suite(gbl_args, common_options.is_export);
1534 ODPH_ERR(
"Error: unable to allocate worker thread\n");
1538 sizeof(gbl_args->cpumask_str));
1541 ODPH_ERR(
"Error: schedule capability failed\n");
1545 gbl_args->max_flow_id = 0;
1553 ODPH_ERR(
"Error: schedule config failed\n");
1556 gbl_args->max_flow_id = 1;
1560 ODPH_ERR(
"Error: unable to query pool capability\n");
1564 buf_num = gbl_args->appl.burst_size * TEST_REPEAT_COUNT;
1567 ODPH_ERR(
"Error: pool size not supported (max %" PRIu32
")\n", capa.
buf.
max_num);
1570 ODPH_ERR(
"Error: cache size not supported (max %" PRIu32
")\n",
1575 gbl_args->buf_size = TEST_BUF_SIZE;
1586 params.
buf.
size = gbl_args->buf_size;
1587 params.
buf.
num = buf_num;
1589 if (gbl_args->appl.cache_size >= 0)
1595 ODPH_ERR(
"Error: pool create failed\n");
1601 memset(&worker_thread, 0,
sizeof(odph_thread_t));
1603 signal(SIGINT, sig_handler);
1611 odph_thread_common_param_init(&thr_common);
1612 thr_common.instance = instance;
1613 thr_common.cpumask = &cpumask;
1614 thr_common.share_param = 1;
1616 odph_thread_param_init(&thr_param);
1617 thr_param.start = gbl_args->suite.suite_fn;
1618 thr_param.arg = gbl_args->suite.args;
1621 odph_thread_create(&worker_thread, &thr_common, &thr_param, 1);
1623 odph_thread_join(&worker_thread, 1);
1625 ret = *gbl_args->suite.retval;
1627 if (ret == 0 && common_options.is_export) {
1628 if (gbl_args->suite.export_fn(gbl_args)) {
1629 ODPH_ERR(
"Error: Export failed\n");
1635 ODPH_ERR(
"Error: pool destroy\n");
1640 ODPH_ERR(
"Error: shm free\n");
1645 ODPH_ERR(
"Error: term local\n");
1650 ODPH_ERR(
"Error: term global\n");
void odp_atomic_store_u32(odp_atomic_u32_t *atom, uint32_t val)
Store value to atomic uint32 variable.
uint32_t odp_buffer_size(odp_buffer_t buf)
Buffer maximum data size.
odp_event_t odp_buffer_to_event(odp_buffer_t buf)
Convert buffer handle to event.
odp_buffer_t odp_buffer_alloc(odp_pool_t pool)
Buffer alloc.
void odp_buffer_free(odp_buffer_t buf)
Buffer free.
int odp_buffer_is_valid(odp_buffer_t buf)
Check that buffer is valid.
odp_buffer_t odp_buffer_from_event(odp_event_t ev)
Get buffer handle from event.
void * odp_buffer_user_area(odp_buffer_t buf)
Buffer user area.
void * odp_buffer_addr(odp_buffer_t buf)
Buffer start address.
int odp_buffer_alloc_multi(odp_pool_t pool, odp_buffer_t buf[], int num)
Allocate multiple buffers.
#define ODP_BUFFER_INVALID
Invalid buffer.
void odp_buffer_free_multi(const odp_buffer_t buf[], int num)
Free multiple buffers.
void odp_buffer_from_event_multi(odp_buffer_t buf[], const odp_event_t ev[], int num)
Convert multiple buffer events to buffer handles.
void odp_buffer_to_event_multi(const odp_buffer_t buf[], odp_event_t ev[], int num)
Convert multiple buffer handles to events.
odp_pool_t odp_buffer_pool(odp_buffer_t buf)
Buffer pool of the buffer.
#define odp_unlikely(x)
Branch unlikely taken.
#define ODP_UNUSED
Intentionally unused variables of functions.
void odp_cpumask_set(odp_cpumask_t *mask, int cpu)
Add CPU to mask.
int odp_cpumask_default_worker(odp_cpumask_t *mask, int num)
Default CPU mask for worker threads.
int odp_cpumask_first(const odp_cpumask_t *mask)
Find first set CPU in mask.
void odp_cpumask_zero(odp_cpumask_t *mask)
Clear entire CPU mask.
int32_t odp_cpumask_to_str(const odp_cpumask_t *mask, char *str, int32_t size)
Format a string from CPU mask.
#define ODP_CPUMASK_STR_SIZE
The maximum number of characters needed to record any CPU mask as a string (output of odp_cpumask_to_...
void odp_event_free_sp(const odp_event_t event[], int num)
Free multiple events to the same pool.
void odp_event_free_multi(const odp_event_t event[], int num)
Free multiple events.
odp_event_subtype_t odp_event_subtype(odp_event_t event)
Event subtype of an event.
void odp_event_free(odp_event_t event)
Free event.
odp_pool_t odp_event_pool(odp_event_t event)
Event pool.
void odp_event_types_multi(const odp_event_t event[], odp_event_type_t type[], odp_event_subtype_t subtype[], int num)
Event types and subtypes of multiple events.
int odp_event_type_multi(const odp_event_t event[], int num, odp_event_type_t *type)
Event type of multiple events.
odp_event_type_t odp_event_type(odp_event_t event)
Event type of an event.
void * odp_event_user_area(odp_event_t event)
Event user area.
odp_event_subtype_t
Event subtype.
void * odp_event_user_area_and_flag(odp_event_t event, int *flag)
Event user area and flag.
odp_event_type_t
Event type.
void odp_event_flow_id_set(odp_event_t event, uint32_t flow_id)
Set event flow id value.
uint32_t odp_event_flow_id(odp_event_t event)
Event flow id value.
odp_event_type_t odp_event_types(odp_event_t event, odp_event_subtype_t *subtype)
Event type and subtype of an event.
int odp_event_is_valid(odp_event_t event)
Check that event is valid.
void odp_init_param_init(odp_init_t *param)
Initialize the odp_init_t to default values for all fields.
#define ODP_STATIC_ASSERT(cond, msg)
Compile time assertion macro.
int odp_init_local(odp_instance_t instance, odp_thread_type_t thr_type)
Thread local ODP initialization.
int odp_init_global(odp_instance_t *instance, const odp_init_t *params, const odp_platform_init_t *platform_params)
Global ODP initialization.
int odp_term_local(void)
Thread local ODP termination.
int odp_term_global(odp_instance_t instance)
Global ODP termination.
uint64_t odp_instance_t
ODP instance ID.
odp_pool_t odp_pool_create(const char *name, const odp_pool_param_t *param)
Create a pool.
int odp_pool_capability(odp_pool_capability_t *capa)
Query pool capabilities.
void odp_pool_param_init(odp_pool_param_t *param)
Initialize pool params.
int odp_pool_destroy(odp_pool_t pool)
Destroy a pool previously created by odp_pool_create()
void odp_pool_print(odp_pool_t pool)
Print pool info.
#define ODP_POOL_INVALID
Invalid pool.
@ ODP_POOL_BUFFER
Buffer pool.
void odp_schedule_config_init(odp_schedule_config_t *config)
Initialize schedule configuration options.
int odp_schedule_config(const odp_schedule_config_t *config)
Global schedule configuration.
int odp_schedule_capability(odp_schedule_capability_t *capa)
Query scheduler capabilities.
int odp_shm_free(odp_shm_t shm)
Free a contiguous block of shared memory.
void * odp_shm_addr(odp_shm_t shm)
Shared memory block address.
#define ODP_SHM_INVALID
Invalid shared memory block.
odp_shm_t odp_shm_reserve(const char *name, uint64_t size, uint64_t align, uint32_t flags)
Reserve a contiguous block of shared memory.
bool odp_bool_t
Boolean type.
void odp_sys_info_print(void)
Print system info.
@ ODP_THREAD_WORKER
Worker thread.
@ ODP_THREAD_CONTROL
Control thread.
Global initialization parameters.
odp_mem_model_t mem_model
Application memory model.
uint32_t max_num
Maximum number of buffers of any size.
struct odp_pool_capability_t::@133 buf
Buffer pool capabilities
uint32_t max_uarea_size
Maximum user area size in bytes.
uint32_t max_size
Maximum buffer data size in bytes.
uint32_t max_cache_size
Maximum size of thread local cache.
uint32_t uarea_size
Minimum user area size in bytes.
uint32_t num
Number of buffers in the pool.
uint32_t cache_size
Maximum number of buffers cached locally per thread.
uint32_t size
Minimum buffer size in bytes.
odp_pool_type_t type
Pool type.
struct odp_pool_param_t::@138 buf
Parameters for buffer pools.
uint32_t max_flow_id
Maximum flow ID per queue.
uint32_t max_flow_id
Maximum flow ID per queue.