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 : : printf("No. routes = %u\n", (unsigned) NUM_ROUTE_ENTRIES);
70 : :
71 : 0 : print_route_distribution(large_route_table, (uint32_t) NUM_ROUTE_ENTRIES);
72 : :
73 : : /* Only generate IPv6 address of each item in large IPS table,
74 : : * here next_hop is not needed.
75 : : */
76 : 0 : generate_large_ips_table(0);
77 : :
78 : 0 : lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config);
79 [ # # ]: 0 : TEST_LPM_ASSERT(lpm != NULL);
80 : :
81 : : /* Measure add. */
82 : : begin = rte_rdtsc();
83 : :
84 [ # # ]: 0 : for (i = 0; i < NUM_ROUTE_ENTRIES; i++) {
85 [ # # ]: 0 : if (rte_lpm6_add(lpm, &large_route_table[i].ip,
86 : 0 : large_route_table[i].depth, next_hop_add) == 0)
87 : 0 : status++;
88 : : }
89 : : /* End Timer. */
90 : 0 : total_time = rte_rdtsc() - begin;
91 : :
92 : : printf("Unique added entries = %d\n", status);
93 : 0 : printf("Average LPM Add: %g cycles\n",
94 : 0 : (double)total_time / NUM_ROUTE_ENTRIES);
95 : :
96 : : /* Measure single Lookup */
97 : : total_time = 0;
98 : : count = 0;
99 : :
100 [ # # ]: 0 : for (i = 0; i < ITERATIONS; i ++) {
101 : : begin = rte_rdtsc();
102 : :
103 [ # # ]: 0 : for (j = 0; j < NUM_IPS_ENTRIES; j ++) {
104 [ # # ]: 0 : if (rte_lpm6_lookup(lpm, &large_ips_table[j].ip,
105 : : &next_hop_return) != 0)
106 : 0 : count++;
107 : : }
108 : :
109 : 0 : total_time += rte_rdtsc() - begin;
110 : :
111 : : }
112 : 0 : printf("Average LPM Lookup: %.1f cycles (fails = %.1f%%)\n",
113 : 0 : (double)total_time / ((double)ITERATIONS * BATCH_SIZE),
114 : 0 : (count * 100.0) / (double)(ITERATIONS * BATCH_SIZE));
115 : :
116 : : /* Measure bulk Lookup */
117 : : total_time = 0;
118 : : count = 0;
119 : :
120 : : struct rte_ipv6_addr ip_batch[NUM_IPS_ENTRIES];
121 : : int32_t next_hops[NUM_IPS_ENTRIES];
122 : :
123 [ # # ]: 0 : for (i = 0; i < NUM_IPS_ENTRIES; i++)
124 : 0 : ip_batch[i] = large_ips_table[i].ip;
125 : :
126 [ # # ]: 0 : for (i = 0; i < ITERATIONS; i ++) {
127 : :
128 : : /* Lookup per batch */
129 : : begin = rte_rdtsc();
130 : 0 : rte_lpm6_lookup_bulk_func(lpm, ip_batch, next_hops, NUM_IPS_ENTRIES);
131 : 0 : total_time += rte_rdtsc() - begin;
132 : :
133 [ # # ]: 0 : for (j = 0; j < NUM_IPS_ENTRIES; j++)
134 [ # # ]: 0 : if (next_hops[j] < 0)
135 : 0 : count++;
136 : : }
137 : 0 : printf("BULK LPM Lookup: %.1f cycles (fails = %.1f%%)\n",
138 : 0 : (double)total_time / ((double)ITERATIONS * BATCH_SIZE),
139 : 0 : (count * 100.0) / (double)(ITERATIONS * BATCH_SIZE));
140 : :
141 : : /* Delete */
142 : : status = 0;
143 : : begin = rte_rdtsc();
144 : :
145 [ # # ]: 0 : for (i = 0; i < NUM_ROUTE_ENTRIES; i++) {
146 : : /* rte_lpm_delete(lpm, ip, depth) */
147 : 0 : status += rte_lpm6_delete(lpm, &large_route_table[i].ip,
148 : 0 : large_route_table[i].depth);
149 : : }
150 : :
151 : 0 : total_time += rte_rdtsc() - begin;
152 : :
153 : 0 : printf("Average LPM Delete: %g cycles\n",
154 : 0 : (double)total_time / NUM_ROUTE_ENTRIES);
155 : :
156 : 0 : rte_lpm6_delete_all(lpm);
157 : 0 : rte_lpm6_free(lpm);
158 : :
159 : 0 : return 0;
160 : : }
161 : :
162 : 251 : REGISTER_PERF_TEST(lpm6_perf_autotest, test_lpm6_perf);
|