Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(c) 2010-2014 Intel Corporation
3 : : */
4 : :
5 : :
6 : : #include <stdio.h>
7 : : #include <stdint.h>
8 : : #include <stdlib.h>
9 : : #include <string.h>
10 : :
11 : : #include <rte_cycles.h>
12 : : #include <rte_random.h>
13 : : #include <rte_memory.h>
14 : : #include <rte_lpm6.h>
15 : :
16 : : #include "test.h"
17 : : #include "test_lpm6_data.h"
18 : :
19 : : #define TEST_LPM_ASSERT(cond) do { \
20 : : if (!(cond)) { \
21 : : printf("Error at line %d: \n", __LINE__); \
22 : : return -1; \
23 : : } \
24 : : } while(0)
25 : :
26 : : #define ITERATIONS (1 << 10)
27 : : #define BATCH_SIZE 100000
28 : : #define NUMBER_TBL8S (1 << 16)
29 : :
30 : : static void
31 : 0 : print_route_distribution(const struct rules_tbl_entry *table, uint32_t n)
32 : : {
33 : : unsigned i, j;
34 : :
35 : : printf("Route distribution per prefix width: \n");
36 : : printf("DEPTH QUANTITY (PERCENT)\n");
37 : : printf("--------------------------- \n");
38 : :
39 : : /* Count depths. */
40 [ # # ]: 0 : for(i = 1; i <= 128; i++) {
41 : : unsigned depth_counter = 0;
42 : : double percent_hits;
43 : :
44 [ # # ]: 0 : for (j = 0; j < n; j++)
45 [ # # ]: 0 : if (table[j].depth == (uint8_t) i)
46 : 0 : depth_counter++;
47 : :
48 : 0 : percent_hits = ((double)depth_counter)/((double)n) * 100;
49 : : printf("%.2u%15u (%.2f)\n", i, depth_counter, percent_hits);
50 : : }
51 : : printf("\n");
52 : 0 : }
53 : :
54 : : static int
55 : 0 : test_lpm6_perf(void)
56 : : {
57 : : struct rte_lpm6 *lpm = NULL;
58 : : struct rte_lpm6_config config;
59 : : uint64_t begin, total_time;
60 : : unsigned i, j;
61 : 0 : uint32_t next_hop_add = 0xAA, next_hop_return = 0;
62 : : int status = 0;
63 : : int64_t count = 0;
64 : :
65 : 0 : config.max_rules = 1000000;
66 : 0 : config.number_tbl8s = NUMBER_TBL8S;
67 : 0 : config.flags = 0;
68 : :
69 : 0 : rte_srand(rte_rdtsc());
70 : :
71 : : printf("No. routes = %u\n", (unsigned) NUM_ROUTE_ENTRIES);
72 : :
73 : 0 : print_route_distribution(large_route_table, (uint32_t) NUM_ROUTE_ENTRIES);
74 : :
75 : : /* Only generate IPv6 address of each item in large IPS table,
76 : : * here next_hop is not needed.
77 : : */
78 : 0 : generate_large_ips_table(0);
79 : :
80 : 0 : lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config);
81 [ # # ]: 0 : TEST_LPM_ASSERT(lpm != NULL);
82 : :
83 : : /* Measure add. */
84 : : begin = rte_rdtsc();
85 : :
86 [ # # ]: 0 : for (i = 0; i < NUM_ROUTE_ENTRIES; i++) {
87 [ # # ]: 0 : if (rte_lpm6_add(lpm, large_route_table[i].ip,
88 : 0 : large_route_table[i].depth, next_hop_add) == 0)
89 : 0 : status++;
90 : : }
91 : : /* End Timer. */
92 : 0 : total_time = rte_rdtsc() - begin;
93 : :
94 : : printf("Unique added entries = %d\n", status);
95 : 0 : printf("Average LPM Add: %g cycles\n",
96 : 0 : (double)total_time / NUM_ROUTE_ENTRIES);
97 : :
98 : : /* Measure single Lookup */
99 : : total_time = 0;
100 : : count = 0;
101 : :
102 [ # # ]: 0 : for (i = 0; i < ITERATIONS; i ++) {
103 : : begin = rte_rdtsc();
104 : :
105 [ # # ]: 0 : for (j = 0; j < NUM_IPS_ENTRIES; j ++) {
106 [ # # ]: 0 : if (rte_lpm6_lookup(lpm, large_ips_table[j].ip,
107 : : &next_hop_return) != 0)
108 : 0 : count++;
109 : : }
110 : :
111 : 0 : total_time += rte_rdtsc() - begin;
112 : :
113 : : }
114 : 0 : printf("Average LPM Lookup: %.1f cycles (fails = %.1f%%)\n",
115 : 0 : (double)total_time / ((double)ITERATIONS * BATCH_SIZE),
116 : 0 : (count * 100.0) / (double)(ITERATIONS * BATCH_SIZE));
117 : :
118 : : /* Measure bulk Lookup */
119 : : total_time = 0;
120 : : count = 0;
121 : :
122 : : uint8_t ip_batch[NUM_IPS_ENTRIES][16];
123 : : int32_t next_hops[NUM_IPS_ENTRIES];
124 : :
125 [ # # ]: 0 : for (i = 0; i < NUM_IPS_ENTRIES; i++)
126 : 0 : memcpy(ip_batch[i], large_ips_table[i].ip, 16);
127 : :
128 [ # # ]: 0 : for (i = 0; i < ITERATIONS; i ++) {
129 : :
130 : : /* Lookup per batch */
131 : : begin = rte_rdtsc();
132 : 0 : rte_lpm6_lookup_bulk_func(lpm, ip_batch, next_hops, NUM_IPS_ENTRIES);
133 : 0 : total_time += rte_rdtsc() - begin;
134 : :
135 [ # # ]: 0 : for (j = 0; j < NUM_IPS_ENTRIES; j++)
136 [ # # ]: 0 : if (next_hops[j] < 0)
137 : 0 : count++;
138 : : }
139 : 0 : printf("BULK LPM Lookup: %.1f cycles (fails = %.1f%%)\n",
140 : 0 : (double)total_time / ((double)ITERATIONS * BATCH_SIZE),
141 : 0 : (count * 100.0) / (double)(ITERATIONS * BATCH_SIZE));
142 : :
143 : : /* Delete */
144 : : status = 0;
145 : : begin = rte_rdtsc();
146 : :
147 [ # # ]: 0 : for (i = 0; i < NUM_ROUTE_ENTRIES; i++) {
148 : : /* rte_lpm_delete(lpm, ip, depth) */
149 : 0 : status += rte_lpm6_delete(lpm, large_route_table[i].ip,
150 : 0 : large_route_table[i].depth);
151 : : }
152 : :
153 : 0 : total_time += rte_rdtsc() - begin;
154 : :
155 : 0 : printf("Average LPM Delete: %g cycles\n",
156 : 0 : (double)total_time / NUM_ROUTE_ENTRIES);
157 : :
158 : 0 : rte_lpm6_delete_all(lpm);
159 : 0 : rte_lpm6_free(lpm);
160 : :
161 : 0 : return 0;
162 : : }
163 : :
164 : 235 : REGISTER_PERF_TEST(lpm6_perf_autotest, test_lpm6_perf);
|