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