1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2017 Cavium, Inc
3  */
4 
5 #include "test.h"
6 
7 #include <stdio.h>
8 #include <unistd.h>
9 #include <inttypes.h>
10 
11 #include <rte_common.h>
12 #include <rte_cycles.h>
13 #include <rte_random.h>
14 #include <rte_reciprocal.h>
15 
16 #define MAX_ITERATIONS	(1ULL << 32)
17 #define DIVIDE_ITER	(1ULL << 28)
18 
19 static int
test_reciprocal_division_perf(void)20 test_reciprocal_division_perf(void)
21 {
22 	int result = 0;
23 	uint32_t divisor_u32 = 0;
24 	uint32_t dividend_u32;
25 	uint64_t divisor_u64 = 0;
26 	uint64_t dividend_u64;
27 	volatile uint32_t nresult_u32;
28 	volatile uint32_t rresult_u32;
29 	volatile uint64_t nresult_u64;
30 	volatile uint64_t rresult_u64;
31 	uint64_t start_cyc;
32 	uint64_t split_cyc;
33 	uint64_t end_cyc;
34 	uint64_t tot_cyc_n = 0;
35 	uint64_t tot_cyc_r = 0;
36 	uint64_t i;
37 	struct rte_reciprocal reci_u32 = {0};
38 	struct rte_reciprocal_u64 reci_u64 = {0};
39 
40 	rte_srand(rte_rdtsc());
41 
42 	printf("Validating unsigned 32bit division.\n");
43 	for (i = 0; i < MAX_ITERATIONS; i++) {
44 		/* Change divisor every DIVIDE_ITER iterations. */
45 		if (i % DIVIDE_ITER == 0) {
46 			divisor_u32 = rte_rand();
47 			reci_u32 = rte_reciprocal_value(divisor_u32);
48 		}
49 
50 		dividend_u32 = rte_rand();
51 
52 		start_cyc = rte_rdtsc();
53 		nresult_u32 = dividend_u32 / divisor_u32;
54 		split_cyc = rte_rdtsc();
55 		rresult_u32 = rte_reciprocal_divide(dividend_u32,
56 				reci_u32);
57 		end_cyc = rte_rdtsc();
58 
59 		tot_cyc_n += split_cyc - start_cyc;
60 		tot_cyc_r += end_cyc - split_cyc;
61 		if (nresult_u32 != rresult_u32) {
62 			printf("Division failed, expected %"PRIu32" "
63 					"result %"PRIu32"",
64 					nresult_u32, rresult_u32);
65 			result = 1;
66 			break;
67 		}
68 	}
69 	printf("32bit Division results:\n");
70 	printf("Total number of cycles normal division     : %"PRIu64"\n",
71 			tot_cyc_n);
72 	printf("Total number of cycles reciprocal division : %"PRIu64"\n",
73 			tot_cyc_r);
74 	printf("Cycles per division(normal) : %3.2f\n",
75 			((double)tot_cyc_n)/i);
76 	printf("Cycles per division(reciprocal) : %3.2f\n\n",
77 			((double)tot_cyc_r)/i);
78 
79 	tot_cyc_n = 0;
80 	tot_cyc_r = 0;
81 
82 	printf("Validating unsigned 64bit division.\n");
83 	for (i = 0; i < MAX_ITERATIONS; i++) {
84 		/* Change divisor every DIVIDE_ITER iterations. */
85 		if (i % DIVIDE_ITER == 0) {
86 			divisor_u64 = rte_rand();
87 			reci_u64 = rte_reciprocal_value_u64(divisor_u64);
88 		}
89 
90 		dividend_u64 = rte_rand();
91 
92 		start_cyc = rte_rdtsc();
93 		nresult_u64 = dividend_u64 / divisor_u64;
94 		split_cyc = rte_rdtsc();
95 		rresult_u64 = rte_reciprocal_divide_u64(dividend_u64,
96 				&reci_u64);
97 		end_cyc = rte_rdtsc();
98 
99 		tot_cyc_n += split_cyc - start_cyc;
100 		tot_cyc_r += end_cyc - split_cyc;
101 		if (nresult_u64 != rresult_u64) {
102 			printf("Division failed, expected %"PRIu64" "
103 					"result %"PRIu64"",
104 					nresult_u64, rresult_u64);
105 			result = 1;
106 			break;
107 		}
108 	}
109 	printf("64bit Division results:\n");
110 	printf("Total number of cycles normal division     : %"PRIu64"\n",
111 			tot_cyc_n);
112 	printf("Total number of cycles reciprocal division : %"PRIu64"\n",
113 			tot_cyc_r);
114 	printf("Cycles per division(normal) : %3.2f\n",
115 			((double)tot_cyc_n)/i);
116 	printf("Cycles per division(reciprocal) : %3.2f\n\n",
117 			((double)tot_cyc_r)/i);
118 
119 	tot_cyc_n = 0;
120 	tot_cyc_r = 0;
121 
122 	printf("Validating unsigned 64bit division with 32bit divisor.\n");
123 	for (i = 0; i < MAX_ITERATIONS; i++) {
124 		/* Change divisor every DIVIDE_ITER iterations. */
125 		if (i % DIVIDE_ITER == 0) {
126 			divisor_u64 = rte_rand() >> 32;
127 			reci_u64 = rte_reciprocal_value_u64(divisor_u64);
128 		}
129 
130 		dividend_u64 = rte_rand();
131 
132 		start_cyc = rte_rdtsc();
133 		nresult_u64 = dividend_u64 / divisor_u64;
134 		split_cyc = rte_rdtsc();
135 		rresult_u64 = rte_reciprocal_divide_u64(dividend_u64,
136 				&reci_u64);
137 		end_cyc = rte_rdtsc();
138 
139 		tot_cyc_n += split_cyc - start_cyc;
140 		tot_cyc_r += end_cyc - split_cyc;
141 		if (nresult_u64 != rresult_u64) {
142 			printf("Division failed, expected %"PRIu64" "
143 					"result %"PRIu64"",
144 					nresult_u64, rresult_u64);
145 			result = 1;
146 			break;
147 		}
148 	}
149 
150 	printf("64bit Division results:\n");
151 	printf("Total number of cycles normal division     : %"PRIu64"\n",
152 			tot_cyc_n);
153 	printf("Total number of cycles reciprocal division : %"PRIu64"\n",
154 			tot_cyc_r);
155 	printf("Cycles per division(normal) : %3.2f\n",
156 			((double)tot_cyc_n)/i);
157 	printf("Cycles per division(reciprocal) : %3.2f\n\n",
158 			((double)tot_cyc_r)/i);
159 
160 	tot_cyc_n = 0;
161 	tot_cyc_r = 0;
162 
163 	printf("Validating division by power of 2.\n");
164 	for (i = 0; i < 64; i++) {
165 		divisor_u64 = 1ull << i;
166 		reci_u64 = rte_reciprocal_value_u64(divisor_u64);
167 
168 		dividend_u64 = rte_rand();
169 
170 		start_cyc = rte_rdtsc();
171 		nresult_u64 = dividend_u64 / divisor_u64;
172 		split_cyc = rte_rdtsc();
173 		rresult_u64 = rte_reciprocal_divide_u64(dividend_u64,
174 				&reci_u64);
175 		end_cyc = rte_rdtsc();
176 
177 		tot_cyc_n += split_cyc - start_cyc;
178 		tot_cyc_r += end_cyc - split_cyc;
179 		if (nresult_u64 != rresult_u64) {
180 			printf("Division 64 failed, %"PRIu64"/%"PRIu64" = "
181 					"expected %"PRIu64" result %"PRIu64"\n",
182 					dividend_u64, divisor_u64,
183 					nresult_u64, rresult_u64);
184 			result = 1;
185 			break;
186 		}
187 	}
188 	printf("64bit Division results:\n");
189 	printf("Total number of cycles normal division     : %"PRIu64"\n",
190 			tot_cyc_n);
191 	printf("Total number of cycles reciprocal division : %"PRIu64"\n",
192 			tot_cyc_r);
193 	printf("Cycles per division(normal) : %3.2f\n",
194 			((double)tot_cyc_n)/i);
195 	printf("Cycles per division(reciprocal) : %3.2f\n",
196 			((double)tot_cyc_r)/i);
197 
198 	return result;
199 }
200 
201 REGISTER_TEST_COMMAND(reciprocal_division_perf, test_reciprocal_division_perf);
202