1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2017 Intel Corporation
3 */
4
5 #include "test.h"
6
7 #include <stdio.h>
8 #include <inttypes.h>
9
10 #include <rte_lcore.h>
11 #include <rte_cycles.h>
12 #include <rte_malloc.h>
13 #include <rte_random.h>
14 #include <rte_memcpy.h>
15 #include <rte_thash.h>
16 #include <math.h>
17
18 #ifdef RTE_EXEC_ENV_WINDOWS
19 static int
test_member_perf(void)20 test_member_perf(void)
21 {
22 printf("member_perf not supported on Windows, skipping test\n");
23 return TEST_SKIPPED;
24 }
25
26 #else
27
28 #include <rte_member.h>
29
30 #define NUM_KEYSIZES RTE_DIM(hashtest_key_lens)
31 #define NUM_SHUFFLES 10
32 #define MAX_KEYSIZE 64
33 #define MAX_ENTRIES (1 << 19)
34 #define KEYS_TO_ADD (MAX_ENTRIES * 75 / 100) /* 75% table utilization */
35 #define NUM_LOOKUPS (KEYS_TO_ADD * 5) /* Loop among keys added, several times */
36 #define VBF_SET_CNT 16
37 #define BURST_SIZE 64
38 #define VBF_FALSE_RATE 0.03
39
40 /* for the heavy hitter detection */
41 #define SKETCH_LARGEST_KEY_SIZE (1<<15)
42 #define SKETCH_PKT_SIZE 16
43 #define TOP_K 100
44 #define SKETCH_ERROR_RATE 0.05
45 #define SKETCH_SAMPLE_RATE 0.001
46 #define NUM_ADDS (KEYS_TO_ADD * 20)
47
48 static unsigned int test_socket_id;
49
50 enum sstype {
51 HT = 0,
52 CACHE,
53 VBF,
54 SKETCH,
55 SKETCH_BOUNDED,
56 SKETCH_BYTE,
57 NUM_TYPE
58 };
59
60 enum operations {
61 ADD = 0,
62 LOOKUP,
63 LOOKUP_BULK,
64 LOOKUP_MULTI,
65 LOOKUP_MULTI_BULK,
66 DELETE,
67 LOOKUP_MISS,
68 NUM_OPERATIONS
69 };
70
71 struct member_perf_params {
72 struct rte_member_setsum *setsum[NUM_TYPE];
73 uint32_t key_size;
74 unsigned int cycle;
75 };
76
77 static uint32_t hashtest_key_lens[] = {
78 /* standard key sizes */
79 4, 8, 16, 32, 48, 64,
80 /* IPv4 SRC + DST + protocol, unpadded */
81 9,
82 /* IPv4 5-tuple, unpadded */
83 13,
84 /* IPv6 5-tuple, unpadded */
85 37,
86 /* IPv6 5-tuple, padded to 8-byte boundary */
87 40
88 };
89
90 /* Array to store number of cycles per operation */
91 static uint64_t cycles[NUM_TYPE][NUM_KEYSIZES][NUM_OPERATIONS];
92 static uint64_t false_data[NUM_TYPE][NUM_KEYSIZES];
93 static uint64_t false_data_bulk[NUM_TYPE][NUM_KEYSIZES];
94 static uint64_t false_data_multi[NUM_TYPE][NUM_KEYSIZES];
95 static uint64_t false_data_multi_bulk[NUM_TYPE][NUM_KEYSIZES];
96
97 static uint64_t false_hit[NUM_TYPE][NUM_KEYSIZES];
98
99 static member_set_t data[NUM_TYPE][/* Array to store the data */KEYS_TO_ADD];
100
101 /* Array to store all input keys */
102 static uint8_t keys[KEYS_TO_ADD][MAX_KEYSIZE];
103 static uint8_t hh_keys[KEYS_TO_ADD][MAX_KEYSIZE];
104
105 /* Shuffle the keys that have been added, so lookups will be totally random */
106 static void
shuffle_input_keys(struct member_perf_params * params)107 shuffle_input_keys(struct member_perf_params *params)
108 {
109 member_set_t temp_data;
110 unsigned int i, j;
111 uint32_t swap_idx;
112 uint8_t temp_key[MAX_KEYSIZE];
113
114 for (i = KEYS_TO_ADD - 1; i > 0; i--) {
115 swap_idx = rte_rand() % i;
116 memcpy(temp_key, keys[i], hashtest_key_lens[params->cycle]);
117 memcpy(keys[i], keys[swap_idx],
118 hashtest_key_lens[params->cycle]);
119 memcpy(keys[swap_idx], temp_key,
120 hashtest_key_lens[params->cycle]);
121 for (j = 0; j < NUM_TYPE; j++) {
122 temp_data = data[j][i];
123 data[j][i] = data[j][swap_idx];
124 data[j][swap_idx] = temp_data;
125 }
126 }
127 }
128
key_compare(const void * key1,const void * key2)129 static int key_compare(const void *key1, const void *key2)
130 {
131 return memcmp(key1, key2, MAX_KEYSIZE);
132 }
133
134 struct rte_member_parameters member_params = {
135 .num_keys = MAX_ENTRIES, /* Total hash table entries. */
136 .key_len = 4, /* Length of hash key. */
137
138 /* num_set and false_positive_rate only relevant to vBF */
139 .num_set = VBF_SET_CNT,
140 .false_positive_rate = 0.03,
141 .prim_hash_seed = 0,
142 .sec_hash_seed = 1,
143 .socket_id = 0, /* NUMA Socket ID for memory. */
144 };
145
146 static int
setup_keys_and_data(struct member_perf_params * params,unsigned int cycle,int miss)147 setup_keys_and_data(struct member_perf_params *params, unsigned int cycle,
148 int miss)
149 {
150 unsigned int i, j;
151 int num_duplicates;
152 int distinct_key = 0;
153 int count_down = SKETCH_LARGEST_KEY_SIZE;
154 uint32_t swap_idx;
155 uint8_t temp_key[MAX_KEYSIZE];
156
157 params->key_size = hashtest_key_lens[cycle];
158 params->cycle = cycle;
159
160 /* Reset all arrays */
161 for (i = 0; i < params->key_size; i++)
162 keys[0][i] = 0;
163
164 /* Generate a list of keys, some of which may be duplicates */
165 for (i = 0; i < KEYS_TO_ADD; i++) {
166 for (j = 0; j < params->key_size; j++)
167 keys[i][j] = rte_rand() & 0xFF;
168
169 data[HT][i] = data[CACHE][i] = (rte_rand() & 0x7FFE) + 1;
170 data[VBF][i] = rte_rand() % VBF_SET_CNT + 1;
171 }
172
173 /* Remove duplicates from the keys array */
174 do {
175 num_duplicates = 0;
176
177 /* Sort the list of keys to make it easier to find duplicates */
178 qsort(keys, KEYS_TO_ADD, MAX_KEYSIZE, key_compare);
179
180 /* Sift through the list of keys and look for duplicates */
181 for (i = 0; i < KEYS_TO_ADD - 1; i++) {
182 if (memcmp(keys[i], keys[i + 1],
183 params->key_size) == 0) {
184 /* This key already exists, try again */
185 num_duplicates++;
186 for (j = 0; j < params->key_size; j++)
187 keys[i][j] = rte_rand() & 0xFF;
188 }
189 }
190 } while (num_duplicates != 0);
191
192 /* Shuffle the random values again */
193 shuffle_input_keys(params);
194
195 for (i = 0; i < KEYS_TO_ADD; i++) {
196 if (count_down == 0) {
197 distinct_key++;
198 count_down = ceil((double)SKETCH_LARGEST_KEY_SIZE /
199 (distinct_key + 1));
200 }
201 memcpy(hh_keys[i], keys[distinct_key], params->key_size);
202 count_down--;
203 }
204
205 for (i = KEYS_TO_ADD - 1; i > 0; i--) {
206 swap_idx = rte_rand() % i;
207 memcpy(temp_key, hh_keys[i], params->key_size);
208 memcpy(hh_keys[i], hh_keys[swap_idx], params->key_size);
209 memcpy(hh_keys[swap_idx], temp_key, params->key_size);
210 }
211
212 /* For testing miss lookup, we insert half and lookup the other half */
213 unsigned int entry_cnt, bf_key_cnt;
214 if (!miss) {
215 entry_cnt = MAX_ENTRIES;
216 bf_key_cnt = KEYS_TO_ADD;
217 } else {
218 entry_cnt = MAX_ENTRIES / 2;
219 bf_key_cnt = KEYS_TO_ADD / 2;
220 }
221 member_params.false_positive_rate = VBF_FALSE_RATE;
222 member_params.key_len = params->key_size;
223 member_params.socket_id = test_socket_id;
224 member_params.num_keys = entry_cnt;
225 member_params.name = "test_member_ht";
226 member_params.is_cache = 0;
227 member_params.type = RTE_MEMBER_TYPE_HT;
228 params->setsum[HT] = rte_member_create(&member_params);
229 if (params->setsum[HT] == NULL)
230 fprintf(stderr, "ht create fail\n");
231
232 member_params.name = "test_member_cache";
233 member_params.is_cache = 1;
234 params->setsum[CACHE] = rte_member_create(&member_params);
235 if (params->setsum[CACHE] == NULL)
236 fprintf(stderr, "CACHE create fail\n");
237
238 member_params.name = "test_member_vbf";
239 member_params.type = RTE_MEMBER_TYPE_VBF;
240 member_params.num_keys = bf_key_cnt;
241 params->setsum[VBF] = rte_member_create(&member_params);
242 if (params->setsum[VBF] == NULL)
243 fprintf(stderr, "VBF create fail\n");
244
245 member_params.name = "test_member_sketch";
246 member_params.key_len = params->key_size;
247 member_params.type = RTE_MEMBER_TYPE_SKETCH;
248 member_params.error_rate = SKETCH_ERROR_RATE;
249 member_params.sample_rate = SKETCH_SAMPLE_RATE;
250 member_params.extra_flag = 0;
251 member_params.top_k = TOP_K;
252 member_params.prim_hash_seed = rte_rdtsc();
253 params->setsum[SKETCH] = rte_member_create(&member_params);
254 if (params->setsum[SKETCH] == NULL)
255 fprintf(stderr, "sketch create fail\n");
256
257 member_params.name = "test_member_sketch_bounded";
258 member_params.key_len = params->key_size;
259 member_params.type = RTE_MEMBER_TYPE_SKETCH;
260 member_params.error_rate = SKETCH_ERROR_RATE;
261 member_params.sample_rate = SKETCH_SAMPLE_RATE;
262 member_params.extra_flag |= RTE_MEMBER_SKETCH_ALWAYS_BOUNDED;
263 member_params.top_k = TOP_K;
264 member_params.prim_hash_seed = rte_rdtsc();
265 params->setsum[SKETCH_BOUNDED] = rte_member_create(&member_params);
266 if (params->setsum[SKETCH_BOUNDED] == NULL)
267 fprintf(stderr, "sketch create fail\n");
268
269 member_params.name = "test_member_sketch_byte";
270 member_params.key_len = params->key_size;
271 member_params.type = RTE_MEMBER_TYPE_SKETCH;
272 member_params.error_rate = SKETCH_ERROR_RATE;
273 member_params.sample_rate = SKETCH_SAMPLE_RATE;
274 member_params.extra_flag |= RTE_MEMBER_SKETCH_COUNT_BYTE;
275 member_params.top_k = TOP_K;
276 member_params.prim_hash_seed = rte_rdtsc();
277 params->setsum[SKETCH_BYTE] = rte_member_create(&member_params);
278 if (params->setsum[SKETCH_BYTE] == NULL)
279 fprintf(stderr, "sketch create fail\n");
280
281
282 for (i = 0; i < NUM_TYPE; i++) {
283 if (params->setsum[i] == NULL)
284 return -1;
285 }
286
287 return 0;
288 }
289
290 static int
timed_adds(struct member_perf_params * params,int type)291 timed_adds(struct member_perf_params *params, int type)
292 {
293 const uint64_t start_tsc = rte_rdtsc();
294 unsigned int i, a;
295 int32_t ret;
296
297 for (i = 0; i < KEYS_TO_ADD; i++) {
298 ret = rte_member_add(params->setsum[type], &keys[i],
299 data[type][i]);
300 if (ret < 0) {
301 printf("Error %d in rte_member_add - key=0x", ret);
302 for (a = 0; a < params->key_size; a++)
303 printf("%02x", keys[i][a]);
304 printf(" value=%d, type: %d\n", data[type][i], type);
305
306 return -1;
307 }
308 }
309
310 const uint64_t end_tsc = rte_rdtsc();
311 const uint64_t time_taken = end_tsc - start_tsc;
312
313 cycles[type][params->cycle][ADD] = time_taken / KEYS_TO_ADD;
314 return 0;
315 }
316
317 static int
timed_adds_sketch(struct member_perf_params * params,int type)318 timed_adds_sketch(struct member_perf_params *params, int type)
319 {
320 const uint64_t start_tsc = rte_rdtsc();
321 unsigned int i, j, a;
322 int32_t ret;
323
324 for (i = 0; i < NUM_ADDS / KEYS_TO_ADD; i++) {
325 for (j = 0; j < KEYS_TO_ADD; j++) {
326 if (type == SKETCH_BYTE)
327 ret = rte_member_add_byte_count(params->setsum[type],
328 &hh_keys[j], SKETCH_PKT_SIZE);
329 else
330 ret = rte_member_add(params->setsum[type], &hh_keys[j], 1);
331 if (ret < 0) {
332 printf("Error %d in rte_member_add - key=0x", ret);
333 for (a = 0; a < params->key_size; a++)
334 printf("%02x", hh_keys[j][a]);
335 printf("type: %d\n", type);
336
337 return -1;
338 }
339 }
340 }
341
342 const uint64_t end_tsc = rte_rdtsc();
343 const uint64_t time_taken = end_tsc - start_tsc;
344
345 cycles[type][params->cycle][ADD] = time_taken / NUM_ADDS;
346
347 return 0;
348 }
349
350 static int
timed_lookups(struct member_perf_params * params,int type)351 timed_lookups(struct member_perf_params *params, int type)
352 {
353 unsigned int i, j;
354
355 false_data[type][params->cycle] = 0;
356
357 const uint64_t start_tsc = rte_rdtsc();
358 member_set_t result;
359 int ret;
360
361 for (i = 0; i < NUM_LOOKUPS / KEYS_TO_ADD; i++) {
362 for (j = 0; j < KEYS_TO_ADD; j++) {
363 ret = rte_member_lookup(params->setsum[type], &keys[j],
364 &result);
365 if (ret < 0) {
366 printf("lookup wrong internally");
367 return -1;
368 }
369 if (type == HT && result == RTE_MEMBER_NO_MATCH) {
370 printf("HT mode shouldn't have false negative");
371 return -1;
372 }
373 if (result != data[type][j])
374 false_data[type][params->cycle]++;
375 }
376 }
377
378 const uint64_t end_tsc = rte_rdtsc();
379 const uint64_t time_taken = end_tsc - start_tsc;
380
381 cycles[type][params->cycle][LOOKUP] = time_taken / NUM_LOOKUPS;
382
383 return 0;
384 }
385
386 static int
timed_lookups_sketch(struct member_perf_params * params,int type)387 timed_lookups_sketch(struct member_perf_params *params, int type)
388 {
389 unsigned int i, j;
390
391 false_data[type][params->cycle] = 0;
392
393 const uint64_t start_tsc = rte_rdtsc();
394 member_set_t result;
395 int ret;
396
397 for (i = 0; i < NUM_LOOKUPS / KEYS_TO_ADD; i++) {
398 for (j = 0; j < KEYS_TO_ADD; j++) {
399 ret = rte_member_lookup(params->setsum[type], &hh_keys[j],
400 &result);
401 if (ret < 0) {
402 printf("lookup wrong internally");
403 return -1;
404 }
405 }
406 }
407
408 const uint64_t end_tsc = rte_rdtsc();
409 const uint64_t time_taken = end_tsc - start_tsc;
410
411 cycles[type][params->cycle][LOOKUP] = time_taken / NUM_LOOKUPS;
412
413 return 0;
414 }
415
416 static int
timed_lookups_bulk(struct member_perf_params * params,int type)417 timed_lookups_bulk(struct member_perf_params *params, int type)
418 {
419 unsigned int i, j, k;
420 member_set_t result[BURST_SIZE] = {0};
421 const void *keys_burst[BURST_SIZE];
422 int ret;
423
424 false_data_bulk[type][params->cycle] = 0;
425
426 const uint64_t start_tsc = rte_rdtsc();
427
428 for (i = 0; i < NUM_LOOKUPS / KEYS_TO_ADD; i++) {
429 for (j = 0; j < KEYS_TO_ADD / BURST_SIZE; j++) {
430 for (k = 0; k < BURST_SIZE; k++)
431 keys_burst[k] = keys[j * BURST_SIZE + k];
432
433 ret = rte_member_lookup_bulk(params->setsum[type],
434 keys_burst,
435 BURST_SIZE,
436 result);
437 if (ret <= 0) {
438 printf("lookup bulk has wrong return value\n");
439 return -1;
440 }
441 for (k = 0; k < BURST_SIZE; k++) {
442 uint32_t data_idx = j * BURST_SIZE + k;
443 if (type == HT && result[k] ==
444 RTE_MEMBER_NO_MATCH) {
445 printf("HT mode shouldn't have "
446 "false negative");
447 return -1;
448 }
449 if (result[k] != data[type][data_idx])
450 false_data_bulk[type][params->cycle]++;
451 }
452 }
453 }
454
455 const uint64_t end_tsc = rte_rdtsc();
456 const uint64_t time_taken = end_tsc - start_tsc;
457
458 cycles[type][params->cycle][LOOKUP_BULK] = time_taken / NUM_LOOKUPS;
459
460 return 0;
461 }
462
463 static int
timed_lookups_multimatch(struct member_perf_params * params,int type)464 timed_lookups_multimatch(struct member_perf_params *params, int type)
465 {
466 unsigned int i, j;
467 member_set_t result[RTE_MEMBER_BUCKET_ENTRIES] = {0};
468 int ret;
469 false_data_multi[type][params->cycle] = 0;
470
471 const uint64_t start_tsc = rte_rdtsc();
472
473 for (i = 0; i < NUM_LOOKUPS / KEYS_TO_ADD; i++) {
474 for (j = 0; j < KEYS_TO_ADD; j++) {
475 ret = rte_member_lookup_multi(params->setsum[type],
476 &keys[j], RTE_MEMBER_BUCKET_ENTRIES, result);
477 if (type != CACHE && ret <= 0) {
478 printf("lookup multi has wrong return value %d,"
479 "type %d\n", ret, type);
480 }
481 if (type == HT && ret == 0) {
482 printf("HT mode shouldn't have false negative");
483 return -1;
484 }
485 /*
486 * For performance test purpose, we do not iterate all
487 * results here. We assume most likely each key can only
488 * find one match which is result[0].
489 */
490 if (result[0] != data[type][j])
491 false_data_multi[type][params->cycle]++;
492 }
493 }
494
495 const uint64_t end_tsc = rte_rdtsc();
496 const uint64_t time_taken = end_tsc - start_tsc;
497
498 cycles[type][params->cycle][LOOKUP_MULTI] = time_taken / NUM_LOOKUPS;
499
500 return 0;
501 }
502
503 static int
timed_lookups_multimatch_bulk(struct member_perf_params * params,int type)504 timed_lookups_multimatch_bulk(struct member_perf_params *params, int type)
505 {
506 unsigned int i, j, k;
507 member_set_t result[BURST_SIZE][RTE_MEMBER_BUCKET_ENTRIES] = {{0} };
508 const void *keys_burst[BURST_SIZE];
509 uint32_t match_count[BURST_SIZE];
510 int ret;
511
512 false_data_multi_bulk[type][params->cycle] = 0;
513
514 const uint64_t start_tsc = rte_rdtsc();
515
516 for (i = 0; i < NUM_LOOKUPS / KEYS_TO_ADD; i++) {
517 for (j = 0; j < KEYS_TO_ADD / BURST_SIZE; j++) {
518 for (k = 0; k < BURST_SIZE; k++)
519 keys_burst[k] = keys[j * BURST_SIZE + k];
520
521 ret = rte_member_lookup_multi_bulk(
522 params->setsum[type],
523 keys_burst, BURST_SIZE,
524 RTE_MEMBER_BUCKET_ENTRIES, match_count,
525 (member_set_t *)result);
526 if (ret < 0) {
527 printf("lookup multimatch bulk has wrong return"
528 " value\n");
529 return -1;
530 }
531 for (k = 0; k < BURST_SIZE; k++) {
532 if (type != CACHE && match_count[k] == 0) {
533 printf("lookup multimatch bulk get "
534 "wrong match count\n");
535 return -1;
536 }
537 if (type == HT && match_count[k] == 0) {
538 printf("HT mode shouldn't have "
539 "false negative");
540 return -1;
541 }
542 uint32_t data_idx = j * BURST_SIZE + k;
543 if (result[k][0] != data[type][data_idx])
544 false_data_multi_bulk[type][params->cycle]++;
545 }
546 }
547 }
548
549 const uint64_t end_tsc = rte_rdtsc();
550 const uint64_t time_taken = end_tsc - start_tsc;
551
552 cycles[type][params->cycle][LOOKUP_MULTI_BULK] = time_taken /
553 NUM_LOOKUPS;
554
555 return 0;
556 }
557
558 static int
timed_deletes(struct member_perf_params * params,int type)559 timed_deletes(struct member_perf_params *params, int type)
560 {
561 unsigned int i;
562 int32_t ret;
563
564 if (type == VBF)
565 return 0;
566 const uint64_t start_tsc = rte_rdtsc();
567 for (i = 0; i < KEYS_TO_ADD; i++) {
568 ret = rte_member_delete(params->setsum[type], &keys[i],
569 data[type][i]);
570 if (type != CACHE && ret < 0) {
571 printf("delete error\n");
572 return -1;
573 }
574 }
575
576 const uint64_t end_tsc = rte_rdtsc();
577 const uint64_t time_taken = end_tsc - start_tsc;
578
579 cycles[type][params->cycle][DELETE] = time_taken / KEYS_TO_ADD;
580
581 return 0;
582 }
583
584 static int
timed_miss_lookup(struct member_perf_params * params,int type)585 timed_miss_lookup(struct member_perf_params *params, int type)
586 {
587 unsigned int i, j;
588 int ret;
589
590 false_hit[type][params->cycle] = 0;
591
592 for (i = 0; i < KEYS_TO_ADD / 2; i++) {
593 ret = rte_member_add(params->setsum[type], &keys[i],
594 data[type][i]);
595 if (ret < 0) {
596 unsigned int a;
597 printf("Error %d in rte_member_add - key=0x", ret);
598 for (a = 0; a < params->key_size; a++)
599 printf("%02x", keys[i][a]);
600 printf(" value=%d, type: %d\n", data[type][i], type);
601
602 return -1;
603 }
604 }
605
606 const uint64_t start_tsc = rte_rdtsc();
607 member_set_t result;
608
609 for (i = 0; i < 2 * NUM_LOOKUPS / KEYS_TO_ADD; i++) {
610 for (j = KEYS_TO_ADD / 2; j < KEYS_TO_ADD; j++) {
611 ret = rte_member_lookup(params->setsum[type], &keys[j],
612 &result);
613 if (ret < 0) {
614 printf("lookup wrong internally");
615 return -1;
616 }
617 if (result != RTE_MEMBER_NO_MATCH)
618 false_hit[type][params->cycle]++;
619 }
620 }
621
622 const uint64_t end_tsc = rte_rdtsc();
623 const uint64_t time_taken = end_tsc - start_tsc;
624
625 cycles[type][params->cycle][LOOKUP_MISS] = time_taken / NUM_LOOKUPS;
626
627 return 0;
628 }
629
630 static void
perform_frees(struct member_perf_params * params)631 perform_frees(struct member_perf_params *params)
632 {
633 int i;
634 for (i = 0; i < NUM_TYPE; i++) {
635 if (params->setsum[i] != NULL) {
636 rte_member_free(params->setsum[i]);
637 params->setsum[i] = NULL;
638 }
639 }
640 }
641
642 static int
exit_with_fail(const char * testname,struct member_perf_params * params,unsigned int i,unsigned int j)643 exit_with_fail(const char *testname, struct member_perf_params *params,
644 unsigned int i, unsigned int j)
645 {
646 printf("<<<<<Test %s failed at keysize %d iteration %d type %d>>>>>\n",
647 testname, hashtest_key_lens[params->cycle], i, j);
648 perform_frees(params);
649 return -1;
650 }
651
652 static int
run_all_tbl_perf_tests(void)653 run_all_tbl_perf_tests(void)
654 {
655 unsigned int i, j, k;
656 struct member_perf_params params;
657
658 printf("Measuring performance, please wait\n");
659 fflush(stdout);
660
661 test_socket_id = rte_socket_id();
662
663 for (i = 0; i < NUM_KEYSIZES; i++) {
664 if (setup_keys_and_data(¶ms, i, 0) < 0) {
665 printf("Could not create keys/data/table\n");
666 return -1;
667 }
668 for (j = 0; j < SKETCH; j++) {
669
670 if (timed_adds(¶ms, j) < 0)
671 return exit_with_fail("timed_adds", ¶ms,
672 i, j);
673
674 for (k = 0; k < NUM_SHUFFLES; k++)
675 shuffle_input_keys(¶ms);
676
677 if (timed_lookups(¶ms, j) < 0)
678 return exit_with_fail("timed_lookups", ¶ms,
679 i, j);
680
681 if (timed_lookups_bulk(¶ms, j) < 0)
682 return exit_with_fail("timed_lookups_bulk",
683 ¶ms, i, j);
684
685 if (timed_lookups_multimatch(¶ms, j) < 0)
686 return exit_with_fail("timed_lookups_multi",
687 ¶ms, i, j);
688
689 if (timed_lookups_multimatch_bulk(¶ms, j) < 0)
690 return exit_with_fail("timed_lookups_multi_bulk",
691 ¶ms, i, j);
692
693 if (timed_deletes(¶ms, j) < 0)
694 return exit_with_fail("timed_deletes", ¶ms,
695 i, j);
696
697 /* Print a dot to show progress on operations */
698 }
699
700 for (j = SKETCH; j < NUM_TYPE; j++) {
701 if (timed_adds_sketch(¶ms, j) < 0)
702 return exit_with_fail
703 ("timed_adds_sketch", ¶ms, i, j);
704
705 if (timed_lookups_sketch(¶ms, j) < 0)
706 return exit_with_fail
707 ("timed_lookups_sketch", ¶ms, i, j);
708 }
709
710 printf(".");
711 fflush(stdout);
712
713 perform_frees(¶ms);
714 }
715
716 /* Test false positive rate using un-inserted keys */
717 for (i = 0; i < NUM_KEYSIZES; i++) {
718 if (setup_keys_and_data(¶ms, i, 1) < 0) {
719 printf("Could not create keys/data/table\n");
720 return -1;
721 }
722 for (j = 0; j < SKETCH; j++) {
723 if (timed_miss_lookup(¶ms, j) < 0)
724 return exit_with_fail("timed_miss_lookup",
725 ¶ms, i, j);
726 }
727 perform_frees(¶ms);
728 }
729
730 printf("\nResults (in CPU cycles/operation)\n");
731 printf("-----------------------------------\n");
732 printf("\n%-18s%-18s%-18s%-18s%-18s%-18s%-18s%-18s%-18s\n",
733 "Keysize", "type", "Add", "Lookup", "Lookup_bulk",
734 "lookup_multi", "lookup_multi_bulk", "Delete",
735 "miss_lookup");
736 for (i = 0; i < NUM_KEYSIZES; i++) {
737 for (j = 0; j < NUM_TYPE; j++) {
738 printf("%-18d", hashtest_key_lens[i]);
739 printf("%-18d", j);
740 for (k = 0; k < NUM_OPERATIONS; k++)
741 printf("%-18"PRIu64, cycles[j][i][k]);
742 printf("\n");
743 }
744 }
745
746 printf("\nFalse results rate (and false positive rate)\n");
747 printf("-----------------------------------\n");
748 printf("\n%-18s%-18s%-18s%-18s%-18s%-18s%-18s\n",
749 "Keysize", "type", "fr_single", "fr_bulk", "fr_multi",
750 "fr_multi_bulk", "false_positive_rate");
751 /* Key size not influence False rate so just print out one key size */
752 for (i = 0; i < 1; i++) {
753 for (j = 0; j < SKETCH; j++) {
754 printf("%-18d", hashtest_key_lens[i]);
755 printf("%-18d", j);
756 printf("%-18f", (float)false_data[j][i] / NUM_LOOKUPS);
757 printf("%-18f", (float)false_data_bulk[j][i] /
758 NUM_LOOKUPS);
759 printf("%-18f", (float)false_data_multi[j][i] /
760 NUM_LOOKUPS);
761 printf("%-18f", (float)false_data_multi_bulk[j][i] /
762 NUM_LOOKUPS);
763 printf("%-18f", (float)false_hit[j][i] /
764 NUM_LOOKUPS);
765 printf("\n");
766 }
767 }
768 return 0;
769 }
770
771 static int
test_member_perf(void)772 test_member_perf(void)
773 {
774
775 if (run_all_tbl_perf_tests() < 0)
776 return -1;
777
778 return 0;
779 }
780
781 #endif /* !RTE_EXEC_ENV_WINDOWS */
782
783 REGISTER_PERF_TEST(member_perf_autotest, test_member_perf);
784