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 (1ULL << 28) 18 : : 19 : : static int 20 : 0 : 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 : 0 : rte_srand(rte_rdtsc()); 41 : : 42 : : printf("Validating unsigned 32bit division.\n"); 43 [ # # ]: 0 : for (i = 0; i < MAX_ITERATIONS; i++) { 44 : : /* Change divisor every DIVIDE_ITER iterations. */ 45 [ # # ]: 0 : if (i % DIVIDE_ITER == 0) { 46 : 0 : divisor_u32 = rte_rand(); 47 : 0 : reci_u32 = rte_reciprocal_value(divisor_u32); 48 : : } 49 : : 50 : 0 : dividend_u32 = rte_rand(); 51 : : 52 : : start_cyc = rte_rdtsc(); 53 : 0 : nresult_u32 = dividend_u32 / divisor_u32; 54 : : split_cyc = rte_rdtsc(); 55 : 0 : rresult_u32 = rte_reciprocal_divide(dividend_u32, 56 : : reci_u32); 57 : : end_cyc = rte_rdtsc(); 58 : : 59 : 0 : tot_cyc_n += split_cyc - start_cyc; 60 : 0 : tot_cyc_r += end_cyc - split_cyc; 61 [ # # ]: 0 : if (nresult_u32 != rresult_u32) { 62 : 0 : printf("Division failed, expected %"PRIu32" " 63 : : "result %"PRIu32"", 64 : : nresult_u32, rresult_u32); 65 : : result = 1; 66 : 0 : 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 [ # # ]: 0 : if (i != 0) { 75 : 0 : printf("Cycles per division(normal) : %3.2f\n", 76 : 0 : ((double)tot_cyc_n)/i); 77 : 0 : printf("Cycles per division(reciprocal) : %3.2f\n\n", 78 : 0 : ((double)tot_cyc_r)/i); 79 : : } 80 : : 81 : : tot_cyc_n = 0; 82 : : tot_cyc_r = 0; 83 : : 84 : : printf("Validating unsigned 64bit division.\n"); 85 [ # # ]: 0 : for (i = 0; i < MAX_ITERATIONS; i++) { 86 : : /* Change divisor every DIVIDE_ITER iterations. */ 87 [ # # ]: 0 : if (i % DIVIDE_ITER == 0) { 88 : 0 : divisor_u64 = rte_rand(); 89 : 0 : reci_u64 = rte_reciprocal_value_u64(divisor_u64); 90 : : } 91 : : 92 : 0 : dividend_u64 = rte_rand(); 93 : : 94 : : start_cyc = rte_rdtsc(); 95 : 0 : nresult_u64 = dividend_u64 / divisor_u64; 96 : : split_cyc = rte_rdtsc(); 97 : 0 : rresult_u64 = rte_reciprocal_divide_u64(dividend_u64, 98 : : &reci_u64); 99 : : end_cyc = rte_rdtsc(); 100 : : 101 : 0 : tot_cyc_n += split_cyc - start_cyc; 102 : 0 : tot_cyc_r += end_cyc - split_cyc; 103 [ # # ]: 0 : if (nresult_u64 != rresult_u64) { 104 : 0 : printf("Division failed, expected %"PRIu64" " 105 : : "result %"PRIu64"", 106 : : nresult_u64, rresult_u64); 107 : : result = 1; 108 : 0 : break; 109 : : } 110 : : } 111 : : printf("64bit Division results:\n"); 112 : : printf("Total number of cycles normal division : %"PRIu64"\n", 113 : : tot_cyc_n); 114 : : printf("Total number of cycles reciprocal division : %"PRIu64"\n", 115 : : tot_cyc_r); 116 [ # # ]: 0 : if (i != 0) { 117 : 0 : printf("Cycles per division(normal) : %3.2f\n", 118 : 0 : ((double)tot_cyc_n)/i); 119 : 0 : printf("Cycles per division(reciprocal) : %3.2f\n\n", 120 : 0 : ((double)tot_cyc_r)/i); 121 : : } 122 : : tot_cyc_n = 0; 123 : : tot_cyc_r = 0; 124 : : 125 : : printf("Validating unsigned 64bit division with 32bit divisor.\n"); 126 [ # # ]: 0 : for (i = 0; i < MAX_ITERATIONS; i++) { 127 : : /* Change divisor every DIVIDE_ITER iterations. */ 128 [ # # ]: 0 : if (i % DIVIDE_ITER == 0) { 129 : 0 : divisor_u64 = rte_rand() >> 32; 130 : 0 : reci_u64 = rte_reciprocal_value_u64(divisor_u64); 131 : : } 132 : : 133 : 0 : dividend_u64 = rte_rand(); 134 : : 135 : : start_cyc = rte_rdtsc(); 136 : 0 : nresult_u64 = dividend_u64 / divisor_u64; 137 : : split_cyc = rte_rdtsc(); 138 : 0 : rresult_u64 = rte_reciprocal_divide_u64(dividend_u64, 139 : : &reci_u64); 140 : : end_cyc = rte_rdtsc(); 141 : : 142 : 0 : tot_cyc_n += split_cyc - start_cyc; 143 : 0 : tot_cyc_r += end_cyc - split_cyc; 144 [ # # ]: 0 : if (nresult_u64 != rresult_u64) { 145 : 0 : printf("Division failed, expected %"PRIu64" " 146 : : "result %"PRIu64"", 147 : : nresult_u64, rresult_u64); 148 : : result = 1; 149 : 0 : break; 150 : : } 151 : : } 152 : : 153 : : printf("64bit Division results:\n"); 154 : : printf("Total number of cycles normal division : %"PRIu64"\n", 155 : : tot_cyc_n); 156 : : printf("Total number of cycles reciprocal division : %"PRIu64"\n", 157 : : tot_cyc_r); 158 [ # # ]: 0 : if (i != 0) { 159 : 0 : printf("Cycles per division(normal) : %3.2f\n", 160 : 0 : ((double)tot_cyc_n)/i); 161 : 0 : printf("Cycles per division(reciprocal) : %3.2f\n\n", 162 : 0 : ((double)tot_cyc_r)/i); 163 : : } 164 : : 165 : : tot_cyc_n = 0; 166 : : tot_cyc_r = 0; 167 : : 168 : : printf("Validating division by power of 2.\n"); 169 [ # # ]: 0 : for (i = 0; i < 64; i++) { 170 : 0 : divisor_u64 = 1ull << i; 171 : 0 : reci_u64 = rte_reciprocal_value_u64(divisor_u64); 172 : : 173 : 0 : dividend_u64 = rte_rand(); 174 : : 175 : : start_cyc = rte_rdtsc(); 176 : 0 : nresult_u64 = dividend_u64 / divisor_u64; 177 : : split_cyc = rte_rdtsc(); 178 : 0 : rresult_u64 = rte_reciprocal_divide_u64(dividend_u64, 179 : : &reci_u64); 180 : : end_cyc = rte_rdtsc(); 181 : : 182 : 0 : tot_cyc_n += split_cyc - start_cyc; 183 : 0 : tot_cyc_r += end_cyc - split_cyc; 184 [ # # ]: 0 : if (nresult_u64 != rresult_u64) { 185 : 0 : printf("Division 64 failed, %"PRIu64"/%"PRIu64" = " 186 : : "expected %"PRIu64" result %"PRIu64"\n", 187 : : dividend_u64, divisor_u64, 188 : : nresult_u64, rresult_u64); 189 : : result = 1; 190 : 0 : break; 191 : : } 192 : : } 193 : : printf("64bit Division results:\n"); 194 : : printf("Total number of cycles normal division : %"PRIu64"\n", 195 : : tot_cyc_n); 196 : : printf("Total number of cycles reciprocal division : %"PRIu64"\n", 197 : : tot_cyc_r); 198 [ # # ]: 0 : if (i != 0) { 199 : 0 : printf("Cycles per division(normal) : %3.2f\n", 200 : 0 : ((double)tot_cyc_n)/i); 201 : 0 : printf("Cycles per division(reciprocal) : %3.2f\n", 202 : 0 : ((double)tot_cyc_r)/i); 203 : : } 204 : : 205 : 0 : return result; 206 : : } 207 : : 208 : 235 : REGISTER_PERF_TEST(reciprocal_division_perf, test_reciprocal_division_perf);