1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2010-2014 Intel Corporation 3 */ 4 5 #include <stdio.h> 6 #include <stdint.h> 7 #include <stdlib.h> 8 #include <string.h> 9 10 #include <rte_cycles.h> 11 #include <rte_random.h> 12 #include <rte_memory.h> 13 14 #include "test.h" 15 16 #ifdef RTE_EXEC_ENV_WINDOWS 17 static int 18 test_fib6_perf(void) 19 { 20 printf("fib6_perf not supported on Windows, skipping test\n"); 21 return TEST_SKIPPED; 22 } 23 24 #else 25 26 #include <rte_fib6.h> 27 28 #include "test_lpm6_data.h" 29 30 #define TEST_FIB_ASSERT(cond) do { \ 31 if (!(cond)) { \ 32 printf("Error at line %d:\n", __LINE__); \ 33 return -1; \ 34 } \ 35 } while (0) 36 37 #define ITERATIONS (1 << 10) 38 #define BATCH_SIZE 100000 39 #define NUMBER_TBL8S (1 << 16) 40 41 static void 42 print_route_distribution(const struct rules_tbl_entry *table, uint32_t n) 43 { 44 unsigned int i, j; 45 46 printf("Route distribution per prefix width:\n"); 47 printf("DEPTH QUANTITY (PERCENT)\n"); 48 printf("---------------------------\n"); 49 50 /* Count depths. */ 51 for (i = 1; i <= 128; i++) { 52 unsigned int depth_counter = 0; 53 double percent_hits; 54 55 for (j = 0; j < n; j++) 56 if (table[j].depth == (uint8_t) i) 57 depth_counter++; 58 59 percent_hits = ((double)depth_counter)/((double)n) * 100; 60 printf("%.2u%15u (%.2f)\n", i, depth_counter, percent_hits); 61 } 62 printf("\n"); 63 } 64 65 static inline uint8_t 66 bits_in_nh(uint8_t nh_sz) 67 { 68 return 8 * (1 << nh_sz); 69 } 70 71 static inline uint64_t 72 get_max_nh(uint8_t nh_sz) 73 { 74 return ((1ULL << (bits_in_nh(nh_sz) - 1)) - 1); 75 } 76 77 static int 78 test_fib6_perf(void) 79 { 80 struct rte_fib6 *fib = NULL; 81 struct rte_fib6_conf conf; 82 uint64_t begin, total_time; 83 unsigned int i, j; 84 uint64_t next_hop_add; 85 int status = 0; 86 int64_t count = 0; 87 uint8_t ip_batch[NUM_IPS_ENTRIES][16]; 88 uint64_t next_hops[NUM_IPS_ENTRIES]; 89 90 conf.type = RTE_FIB6_TRIE; 91 conf.default_nh = 0; 92 conf.max_routes = 1000000; 93 conf.rib_ext_sz = 0; 94 conf.trie.nh_sz = RTE_FIB6_TRIE_4B; 95 conf.trie.num_tbl8 = RTE_MIN(get_max_nh(conf.trie.nh_sz), 1000000U); 96 97 rte_srand(rte_rdtsc()); 98 99 printf("No. routes = %u\n", (unsigned int) NUM_ROUTE_ENTRIES); 100 101 print_route_distribution(large_route_table, 102 (uint32_t)NUM_ROUTE_ENTRIES); 103 104 /* Only generate IPv6 address of each item in large IPS table, 105 * here next_hop is not needed. 106 */ 107 generate_large_ips_table(0); 108 109 fib = rte_fib6_create(__func__, SOCKET_ID_ANY, &conf); 110 TEST_FIB_ASSERT(fib != NULL); 111 112 /* Measure add. */ 113 begin = rte_rdtsc(); 114 115 for (i = 0; i < NUM_ROUTE_ENTRIES; i++) { 116 next_hop_add = (i & ((1 << 14) - 1)) + 1; 117 if (rte_fib6_add(fib, large_route_table[i].ip, 118 large_route_table[i].depth, next_hop_add) == 0) 119 status++; 120 } 121 /* End Timer. */ 122 total_time = rte_rdtsc() - begin; 123 124 printf("Unique added entries = %d\n", status); 125 printf("Average FIB Add: %g cycles\n", 126 (double)total_time / NUM_ROUTE_ENTRIES); 127 128 /* Measure bulk Lookup */ 129 total_time = 0; 130 count = 0; 131 132 for (i = 0; i < NUM_IPS_ENTRIES; i++) 133 memcpy(ip_batch[i], large_ips_table[i].ip, 16); 134 135 for (i = 0; i < ITERATIONS; i++) { 136 137 /* Lookup per batch */ 138 begin = rte_rdtsc(); 139 rte_fib6_lookup_bulk(fib, ip_batch, next_hops, NUM_IPS_ENTRIES); 140 total_time += rte_rdtsc() - begin; 141 142 for (j = 0; j < NUM_IPS_ENTRIES; j++) 143 if (next_hops[j] == 0) 144 count++; 145 } 146 printf("BULK FIB Lookup: %.1f cycles (fails = %.1f%%)\n", 147 (double)total_time / ((double)ITERATIONS * BATCH_SIZE), 148 (count * 100.0) / (double)(ITERATIONS * BATCH_SIZE)); 149 150 /* Delete */ 151 status = 0; 152 begin = rte_rdtsc(); 153 154 for (i = 0; i < NUM_ROUTE_ENTRIES; i++) { 155 /* rte_fib_delete(fib, ip, depth) */ 156 status += rte_fib6_delete(fib, large_route_table[i].ip, 157 large_route_table[i].depth); 158 } 159 160 total_time = rte_rdtsc() - begin; 161 162 printf("Average FIB Delete: %g cycles\n", 163 (double)total_time / NUM_ROUTE_ENTRIES); 164 165 rte_fib6_free(fib); 166 167 return 0; 168 } 169 170 #endif /*ifdef RTE_EXEC_ENV_WINDOWS*/ 171 172 REGISTER_TEST_COMMAND(fib6_perf_autotest, test_fib6_perf); 173