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