Branch data Line data Source code
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 (100)
18 : :
19 : : static int
20 : 0 : test_reciprocal(void)
21 : : {
22 : : int result = 0;
23 : : uint32_t divisor_u32 = 0;
24 : : uint32_t dividend_u32;
25 : : uint32_t nresult_u32;
26 : : uint32_t rresult_u32;
27 : : uint64_t i, j;
28 : : uint64_t divisor_u64 = 0;
29 : : uint64_t dividend_u64;
30 : : uint64_t nresult_u64;
31 : : uint64_t rresult_u64;
32 : : struct rte_reciprocal reci_u32 = {0};
33 : : struct rte_reciprocal_u64 reci_u64 = {0};
34 : :
35 : 0 : rte_srand(rte_rdtsc());
36 : : printf("Validating unsigned 32bit division.\n");
37 [ # # ]: 0 : for (i = 0; i < MAX_ITERATIONS; i++) {
38 : : /* Change divisor every DIVIDE_ITER iterations. */
39 [ # # ]: 0 : if (i % DIVIDE_ITER == 0) {
40 : 0 : divisor_u32 = rte_rand();
41 : 0 : reci_u32 = rte_reciprocal_value(divisor_u32);
42 : : }
43 : :
44 : 0 : dividend_u32 = rte_rand();
45 [ # # ]: 0 : nresult_u32 = dividend_u32 / divisor_u32;
46 : : rresult_u32 = rte_reciprocal_divide(dividend_u32,
47 : : reci_u32);
48 [ # # ]: 0 : if (nresult_u32 != rresult_u32) {
49 : : printf("Division failed, %"PRIu32"/%"PRIu32" = "
50 : : "expected %"PRIu32" result %"PRIu32"\n",
51 : : dividend_u32, divisor_u32,
52 : : nresult_u32, rresult_u32);
53 : : result = 1;
54 : 0 : break;
55 : : }
56 : : }
57 : :
58 : : printf("Validating unsigned 64bit division.\n");
59 [ # # ]: 0 : for (i = 0; i < MAX_ITERATIONS; i++) {
60 : : /* Change divisor every DIVIDE_ITER iterations. */
61 [ # # ]: 0 : if (i % DIVIDE_ITER == 0) {
62 : 0 : divisor_u64 = rte_rand();
63 : 0 : reci_u64 = rte_reciprocal_value_u64(divisor_u64);
64 : : }
65 : :
66 : 0 : dividend_u64 = rte_rand();
67 [ # # ]: 0 : nresult_u64 = dividend_u64 / divisor_u64;
68 : : rresult_u64 = rte_reciprocal_divide_u64(dividend_u64,
69 : : &reci_u64);
70 [ # # ]: 0 : if (nresult_u64 != rresult_u64) {
71 : : printf("Division failed, %"PRIu64"/%"PRIu64" = "
72 : : "expected %"PRIu64" result %"PRIu64"\n",
73 : : dividend_u64, divisor_u64,
74 : : nresult_u64, rresult_u64);
75 : : result = 1;
76 : 0 : break;
77 : : }
78 : : }
79 : :
80 : : printf("Validating unsigned 64bit division with 32bit divisor.\n");
81 [ # # ]: 0 : for (i = 0; i < MAX_ITERATIONS; i++) {
82 : : /* Change divisor every DIVIDE_ITER iterations. */
83 [ # # ]: 0 : if (i % DIVIDE_ITER == 0) {
84 : 0 : divisor_u64 = rte_rand() >> 32;
85 : 0 : reci_u64 = rte_reciprocal_value_u64(divisor_u64);
86 : : }
87 : :
88 : 0 : dividend_u64 = rte_rand();
89 : :
90 [ # # ]: 0 : nresult_u64 = dividend_u64 / divisor_u64;
91 : : rresult_u64 = rte_reciprocal_divide_u64(dividend_u64,
92 : : &reci_u64);
93 : :
94 [ # # ]: 0 : if (nresult_u64 != rresult_u64) {
95 : : printf("Division failed, %"PRIu64"/%"PRIu64" = "
96 : : "expected %"PRIu64" result %"PRIu64"\n",
97 : : dividend_u64, divisor_u64,
98 : : nresult_u64, rresult_u64);
99 : : result = 1;
100 : 0 : break;
101 : : }
102 : : }
103 : :
104 : : printf("Validating division by power of 2.\n");
105 [ # # ]: 0 : for (i = 0; i < 32; i++) {
106 : 0 : divisor_u64 = 1ull << i;
107 : 0 : reci_u64 = rte_reciprocal_value_u64(divisor_u64);
108 : 0 : reci_u32 = rte_reciprocal_value((uint32_t)divisor_u64);
109 : :
110 [ # # ]: 0 : for (j = 0; j < MAX_ITERATIONS >> 4; j++) {
111 : 0 : dividend_u64 = rte_rand();
112 : :
113 [ # # ]: 0 : nresult_u64 = dividend_u64 / divisor_u64;
114 : : rresult_u64 = rte_reciprocal_divide_u64(dividend_u64,
115 : : &reci_u64);
116 : :
117 [ # # ]: 0 : if (nresult_u64 != rresult_u64) {
118 : : printf(
119 : : "Division 64 failed, %"PRIu64"/%"PRIu64" = "
120 : : "expected %"PRIu64" result %"PRIu64"\n",
121 : : dividend_u64, divisor_u64,
122 : : nresult_u64, rresult_u64);
123 : : result = 1;
124 : : }
125 : :
126 : 0 : nresult_u32 = (dividend_u64 >> 32) / divisor_u64;
127 [ # # ]: 0 : rresult_u32 = rte_reciprocal_divide(
128 : : (dividend_u64 >> 32), reci_u32);
129 : :
130 [ # # ]: 0 : if (nresult_u32 != rresult_u32) {
131 : : printf(
132 : : "Division 32 failed, %"PRIu64"/%"PRIu64" = "
133 : : "expected %"PRIu64" result %"PRIu64"\n",
134 : : dividend_u64 >> 32, divisor_u64,
135 : : nresult_u64, rresult_u64);
136 : : result = 1;
137 : 0 : break;
138 : : }
139 : : }
140 : : }
141 : :
142 [ # # ]: 0 : for (; i < 64; i++) {
143 : 0 : divisor_u64 = 1ull << i;
144 : 0 : reci_u64 = rte_reciprocal_value_u64(divisor_u64);
145 : :
146 [ # # ]: 0 : for (j = 0; j < MAX_ITERATIONS >> 4; j++) {
147 : 0 : dividend_u64 = rte_rand();
148 : :
149 [ # # ]: 0 : nresult_u64 = dividend_u64 / divisor_u64;
150 : : rresult_u64 = rte_reciprocal_divide_u64(dividend_u64,
151 : : &reci_u64);
152 : :
153 [ # # ]: 0 : if (nresult_u64 != rresult_u64) {
154 : : printf("Division failed, %"PRIu64"/%"PRIu64" = "
155 : : "expected %"PRIu64" result %"PRIu64"\n",
156 : : dividend_u64, divisor_u64,
157 : : nresult_u64, rresult_u64);
158 : : result = 1;
159 : 0 : break;
160 : : }
161 : : }
162 : : }
163 : :
164 : 0 : return result;
165 : : }
166 : :
167 : 235 : REGISTER_PERF_TEST(reciprocal_division, test_reciprocal);
|