crc/test: add fnv
[fio.git] / crc / test.c
CommitLineData
fec0f21c
JA
1#include <stdio.h>
2#include <stdlib.h>
3#include <string.h>
4
5#include "../fio.h"
6#include "../gettime.h"
9e52966e 7#include "../fio_time.h"
fec0f21c
JA
8#include "../verify.h"
9
10#include "../crc/md5.h"
11#include "../crc/crc64.h"
12#include "../crc/crc32.h"
13#include "../crc/crc32c.h"
14#include "../crc/crc16.h"
15#include "../crc/crc7.h"
16#include "../crc/sha1.h"
17#include "../crc/sha256.h"
18#include "../crc/sha512.h"
844ea602 19#include "../crc/xxhash.h"
f83ffd02 20#include "../crc/murmur3.h"
951984d8 21#include "../crc/fnv.h"
140dda40 22#include "../hash.h"
fec0f21c 23
ea1f1da3
JA
24#include "test.h"
25
f7540869
JA
26#define CHUNK 131072U
27#define NR_CHUNKS 2048U
fec0f21c
JA
28
29struct test_type {
30 const char *name;
31 unsigned int mask;
140dda40
JA
32 void (*fn)(struct test_type *, void *, size_t);
33 uint32_t output;
fec0f21c
JA
34};
35
36enum {
37 T_MD5 = 1U << 0,
38 T_CRC64 = 1U << 1,
39 T_CRC32 = 1U << 2,
40 T_CRC32C = 1U << 3,
41 T_CRC16 = 1U << 4,
42 T_CRC7 = 1U << 5,
43 T_SHA1 = 1U << 6,
44 T_SHA256 = 1U << 7,
45 T_SHA512 = 1U << 8,
844ea602 46 T_XXHASH = 1U << 9,
9f0e365d 47 T_MURMUR3 = 1U << 10,
140dda40 48 T_JHASH = 1U << 11,
951984d8 49 T_FNV = 1U << 12,
fec0f21c
JA
50};
51
140dda40 52static void t_md5(struct test_type *t, void *buf, size_t size)
fec0f21c
JA
53{
54 uint32_t digest[4];
55 struct fio_md5_ctx ctx = { .hash = digest };
fec0f21c
JA
56 int i;
57
58 fio_md5_init(&ctx);
59
9c8566f5 60 for (i = 0; i < NR_CHUNKS; i++) {
24ef7a61 61 fio_md5_update(&ctx, buf, size);
9c8566f5
JA
62 fio_md5_final(&ctx);
63 }
fec0f21c
JA
64}
65
140dda40 66static void t_crc64(struct test_type *t, void *buf, size_t size)
fec0f21c 67{
fec0f21c
JA
68 int i;
69
fec0f21c 70 for (i = 0; i < NR_CHUNKS; i++)
24ef7a61 71 fio_crc64(buf, size);
fec0f21c
JA
72}
73
140dda40 74static void t_crc32(struct test_type *t, void *buf, size_t size)
fec0f21c 75{
fec0f21c
JA
76 int i;
77
fec0f21c 78 for (i = 0; i < NR_CHUNKS; i++)
24ef7a61 79 fio_crc32(buf, size);
fec0f21c
JA
80}
81
140dda40 82static void t_crc32c(struct test_type *t, void *buf, size_t size)
fec0f21c 83{
fec0f21c
JA
84 int i;
85
fec0f21c 86 for (i = 0; i < NR_CHUNKS; i++)
24ef7a61 87 fio_crc32c(buf, size);
fec0f21c
JA
88}
89
140dda40 90static void t_crc16(struct test_type *t, void *buf, size_t size)
fec0f21c 91{
fec0f21c
JA
92 int i;
93
fec0f21c 94 for (i = 0; i < NR_CHUNKS; i++)
24ef7a61 95 fio_crc16(buf, size);
fec0f21c
JA
96}
97
140dda40 98static void t_crc7(struct test_type *t, void *buf, size_t size)
fec0f21c 99{
fec0f21c
JA
100 int i;
101
fec0f21c 102 for (i = 0; i < NR_CHUNKS; i++)
24ef7a61 103 fio_crc7(buf, size);
fec0f21c
JA
104}
105
140dda40 106static void t_sha1(struct test_type *t, void *buf, size_t size)
fec0f21c
JA
107{
108 uint32_t sha[5];
109 struct fio_sha1_ctx ctx = { .H = sha };
fec0f21c
JA
110 int i;
111
112 fio_sha1_init(&ctx);
113
fec0f21c 114 for (i = 0; i < NR_CHUNKS; i++)
24ef7a61 115 fio_sha1_update(&ctx, buf, size);
fec0f21c
JA
116}
117
140dda40 118static void t_sha256(struct test_type *t, void *buf, size_t size)
fec0f21c
JA
119{
120 uint8_t sha[64];
121 struct fio_sha256_ctx ctx = { .buf = sha };
fec0f21c
JA
122 int i;
123
124 fio_sha256_init(&ctx);
125
9c8566f5 126 for (i = 0; i < NR_CHUNKS; i++) {
24ef7a61 127 fio_sha256_update(&ctx, buf, size);
9c8566f5
JA
128 fio_sha256_final(&ctx);
129 }
fec0f21c
JA
130}
131
140dda40 132static void t_sha512(struct test_type *t, void *buf, size_t size)
fec0f21c
JA
133{
134 uint8_t sha[128];
135 struct fio_sha512_ctx ctx = { .buf = sha };
fec0f21c
JA
136 int i;
137
138 fio_sha512_init(&ctx);
139
fec0f21c 140 for (i = 0; i < NR_CHUNKS; i++)
24ef7a61 141 fio_sha512_update(&ctx, buf, size);
fec0f21c
JA
142}
143
140dda40 144static void t_murmur3(struct test_type *t, void *buf, size_t size)
9f0e365d
JA
145{
146 int i;
147
148 for (i = 0; i < NR_CHUNKS; i++)
149 murmurhash3(buf, size, 0x8989);
150}
151
140dda40
JA
152static void t_jhash(struct test_type *t, void *buf, size_t size)
153{
154 int i;
155
156 for (i = 0; i < NR_CHUNKS; i++)
157 t->output += jhash(buf, size, 0x8989);
158}
159
951984d8
JA
160static void t_fnv(struct test_type *t, void *buf, size_t size)
161{
162 int i;
163
164 for (i = 0; i < NR_CHUNKS; i++)
165 t->output += fnv(buf, size, 0x8989);
166}
167
140dda40 168static void t_xxhash(struct test_type *t, void *buf, size_t size)
844ea602
JA
169{
170 void *state;
844ea602
JA
171 int i;
172
173 state = XXH32_init(0x8989);
174
844ea602 175 for (i = 0; i < NR_CHUNKS; i++)
24ef7a61 176 XXH32_update(state, buf, size);
844ea602 177
140dda40 178 t->output = XXH32_digest(state);
844ea602
JA
179}
180
fec0f21c
JA
181static struct test_type t[] = {
182 {
183 .name = "md5",
184 .mask = T_MD5,
185 .fn = t_md5,
186 },
187 {
188 .name = "crc64",
189 .mask = T_CRC64,
190 .fn = t_crc64,
191 },
192 {
193 .name = "crc32",
194 .mask = T_CRC32,
195 .fn = t_crc32,
196 },
197 {
198 .name = "crc32c",
199 .mask = T_CRC32C,
200 .fn = t_crc32c,
201 },
202 {
203 .name = "crc16",
204 .mask = T_CRC16,
205 .fn = t_crc16,
206 },
207 {
208 .name = "crc7",
209 .mask = T_CRC7,
210 .fn = t_crc7,
211 },
212 {
213 .name = "sha1",
214 .mask = T_SHA1,
215 .fn = t_sha1,
216 },
217 {
218 .name = "sha256",
219 .mask = T_SHA256,
220 .fn = t_sha256,
221 },
222 {
223 .name = "sha512",
224 .mask = T_SHA512,
225 .fn = t_sha512,
226 },
844ea602
JA
227 {
228 .name = "xxhash",
229 .mask = T_XXHASH,
230 .fn = t_xxhash,
231 },
9f0e365d
JA
232 {
233 .name = "murmur3",
234 .mask = T_MURMUR3,
235 .fn = t_murmur3,
236 },
140dda40
JA
237 {
238 .name = "jhash",
239 .mask = T_JHASH,
240 .fn = t_jhash,
241 },
951984d8
JA
242 {
243 .name = "fnv",
244 .mask = T_FNV,
245 .fn = t_fnv,
246 },
fec0f21c
JA
247 {
248 .name = NULL,
249 },
250};
251
252static unsigned int get_test_mask(const char *type)
253{
254 char *ostr, *str = strdup(type);
255 unsigned int mask;
256 char *name;
257 int i;
258
259 ostr = str;
260 mask = 0;
261 while ((name = strsep(&str, ",")) != NULL) {
262 for (i = 0; t[i].name; i++) {
f7540869 263 if (!strcmp(t[i].name, name)) {
fec0f21c
JA
264 mask |= t[i].mask;
265 break;
266 }
267 }
268 }
269
270 free(ostr);
271 return mask;
272}
273
782744ef
JA
274static int list_types(void)
275{
276 int i;
277
278 for (i = 0; t[i].name; i++)
279 printf("%s\n", t[i].name);
280
24ef7a61 281 return 1;
782744ef
JA
282}
283
fec0f21c
JA
284int fio_crctest(const char *type)
285{
286 unsigned int test_mask = 0;
287 uint64_t mb = CHUNK * NR_CHUNKS;
ae7e055f 288 struct frand_state state;
24ef7a61
JA
289 int i, first = 1;
290 void *buf;
fec0f21c
JA
291
292 crc32c_intel_probe();
293
294 if (!type)
295 test_mask = ~0U;
782744ef
JA
296 else if (!strcmp(type, "help") || !strcmp(type, "list"))
297 return list_types();
fec0f21c
JA
298 else
299 test_mask = get_test_mask(type);
300
24ef7a61
JA
301 if (!test_mask) {
302 fprintf(stderr, "fio: unknown hash `%s`. Available:\n", type);
303 return list_types();
304 }
305
306 buf = malloc(CHUNK);
ae7e055f
JA
307 init_rand_seed(&state, 0x8989);
308 fill_random_buf(&state, buf, CHUNK);
24ef7a61 309
fec0f21c 310 for (i = 0; t[i].name; i++) {
ae7e055f 311 struct timeval tv;
fec0f21c
JA
312 double mb_sec;
313 uint64_t usec;
d78bbd4c 314 char pre[3];
fec0f21c
JA
315
316 if (!(t[i].mask & test_mask))
317 continue;
318
ae7e055f
JA
319 /*
320 * For first run, make sure CPUs are spun up and that
321 * we've touched the data.
322 */
323 if (first) {
324 usec_spin(100000);
140dda40 325 t[i].fn(&t[i], buf, CHUNK);
ae7e055f
JA
326 }
327
328 fio_gettime(&tv, NULL);
140dda40 329 t[i].fn(&t[i], buf, CHUNK);
ae7e055f 330 usec = utime_since_now(&tv);
24ef7a61 331
fec0f21c
JA
332 mb_sec = (double) mb / (double) usec;
333 mb_sec /= (1.024 * 1.024);
d78bbd4c
JA
334 if (strlen(t[i].name) >= 7)
335 sprintf(pre, "\t");
336 else
337 sprintf(pre, "\t\t");
338 printf("%s:%s%8.2f MB/sec\n", t[i].name, pre, mb_sec);
24ef7a61 339 first = 0;
fec0f21c 340 }
782744ef 341
24ef7a61 342 free(buf);
fec0f21c
JA
343 return 0;
344}