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