6 #include "../gettime.h"
7 #include "../fio_time.h"
8 #include "../lib/rand.h"
11 #include "../crc/md5.h"
12 #include "../crc/crc64.h"
13 #include "../crc/crc32.h"
14 #include "../crc/crc32c.h"
15 #include "../crc/crc16.h"
16 #include "../crc/crc7.h"
17 #include "../crc/sha1.h"
18 #include "../crc/sha256.h"
19 #include "../crc/sha512.h"
20 #include "../crc/sha3.h"
21 #include "../crc/xxhash.h"
22 #include "../crc/murmur3.h"
23 #include "../crc/fnv.h"
29 #define NR_CHUNKS 2048U
34 void (*fn)(struct test_type *, void *, size_t);
52 T_SHA3_224 = 1U << 13,
53 T_SHA3_256 = 1U << 14,
54 T_SHA3_384 = 1U << 15,
55 T_SHA3_512 = 1U << 16,
58 static void t_md5(struct test_type *t, void *buf, size_t size)
61 struct fio_md5_ctx ctx = { .hash = digest };
66 for (i = 0; i < NR_CHUNKS; i++) {
67 fio_md5_update(&ctx, buf, size);
72 static void t_crc64(struct test_type *t, void *buf, size_t size)
76 for (i = 0; i < NR_CHUNKS; i++)
77 t->output += fio_crc64(buf, size);
80 static void t_crc32(struct test_type *t, void *buf, size_t size)
84 for (i = 0; i < NR_CHUNKS; i++)
85 t->output += fio_crc32(buf, size);
88 static void t_crc32c(struct test_type *t, void *buf, size_t size)
92 for (i = 0; i < NR_CHUNKS; i++)
93 t->output += fio_crc32c(buf, size);
96 static void t_crc16(struct test_type *t, void *buf, size_t size)
100 for (i = 0; i < NR_CHUNKS; i++)
101 t->output += fio_crc16(buf, size);
104 static void t_crc7(struct test_type *t, void *buf, size_t size)
108 for (i = 0; i < NR_CHUNKS; i++)
109 t->output += fio_crc7(buf, size);
112 static void t_sha1(struct test_type *t, void *buf, size_t size)
115 struct fio_sha1_ctx ctx = { .H = sha };
120 for (i = 0; i < NR_CHUNKS; i++) {
121 fio_sha1_update(&ctx, buf, size);
122 fio_sha1_final(&ctx);
126 static void t_sha256(struct test_type *t, void *buf, size_t size)
129 struct fio_sha256_ctx ctx = { .buf = sha };
132 fio_sha256_init(&ctx);
134 for (i = 0; i < NR_CHUNKS; i++) {
135 fio_sha256_update(&ctx, buf, size);
136 fio_sha256_final(&ctx);
140 static void t_sha512(struct test_type *t, void *buf, size_t size)
143 struct fio_sha512_ctx ctx = { .buf = sha };
146 fio_sha512_init(&ctx);
148 for (i = 0; i < NR_CHUNKS; i++)
149 fio_sha512_update(&ctx, buf, size);
152 static void t_sha3_224(struct test_type *t, void *buf, size_t size)
154 uint8_t sha[SHA3_224_DIGEST_SIZE];
155 struct fio_sha3_ctx ctx = { .sha = sha };
158 fio_sha3_224_init(&ctx);
160 for (i = 0; i < NR_CHUNKS; i++) {
161 fio_sha3_update(&ctx, buf, size);
162 fio_sha3_final(&ctx);
166 static void t_sha3_256(struct test_type *t, void *buf, size_t size)
168 uint8_t sha[SHA3_256_DIGEST_SIZE];
169 struct fio_sha3_ctx ctx = { .sha = sha };
172 fio_sha3_256_init(&ctx);
174 for (i = 0; i < NR_CHUNKS; i++) {
175 fio_sha3_update(&ctx, buf, size);
176 fio_sha3_final(&ctx);
180 static void t_sha3_384(struct test_type *t, void *buf, size_t size)
182 uint8_t sha[SHA3_384_DIGEST_SIZE];
183 struct fio_sha3_ctx ctx = { .sha = sha };
186 fio_sha3_384_init(&ctx);
188 for (i = 0; i < NR_CHUNKS; i++) {
189 fio_sha3_update(&ctx, buf, size);
190 fio_sha3_final(&ctx);
194 static void t_sha3_512(struct test_type *t, void *buf, size_t size)
196 uint8_t sha[SHA3_512_DIGEST_SIZE];
197 struct fio_sha3_ctx ctx = { .sha = sha };
200 fio_sha3_512_init(&ctx);
202 for (i = 0; i < NR_CHUNKS; i++) {
203 fio_sha3_update(&ctx, buf, size);
204 fio_sha3_final(&ctx);
208 static void t_murmur3(struct test_type *t, void *buf, size_t size)
212 for (i = 0; i < NR_CHUNKS; i++)
213 t->output += murmurhash3(buf, size, 0x8989);
216 static void t_jhash(struct test_type *t, void *buf, size_t size)
220 for (i = 0; i < NR_CHUNKS; i++)
221 t->output += jhash(buf, size, 0x8989);
224 static void t_fnv(struct test_type *t, void *buf, size_t size)
228 for (i = 0; i < NR_CHUNKS; i++)
229 t->output += fnv(buf, size, 0x8989);
232 static void t_xxhash(struct test_type *t, void *buf, size_t size)
237 state = XXH32_init(0x8989);
239 for (i = 0; i < NR_CHUNKS; i++)
240 XXH32_update(state, buf, size);
242 t->output = XXH32_digest(state);
245 static struct test_type t[] = {
336 static unsigned int get_test_mask(const char *type)
338 char *ostr, *str = strdup(type);
345 while ((name = strsep(&str, ",")) != NULL) {
346 for (i = 0; t[i].name; i++) {
347 if (!strcmp(t[i].name, name)) {
358 static int list_types(void)
362 for (i = 0; t[i].name; i++)
363 printf("%s\n", t[i].name);
368 int fio_crctest(const char *type)
370 unsigned int test_mask = 0;
371 uint64_t mb = CHUNK * NR_CHUNKS;
372 struct frand_state state;
376 crc32c_arm64_probe();
377 crc32c_intel_probe();
381 else if (!strcmp(type, "help") || !strcmp(type, "list"))
384 test_mask = get_test_mask(type);
387 fprintf(stderr, "fio: unknown hash `%s`. Available:\n", type);
392 init_rand_seed(&state, 0x8989, 0);
393 fill_random_buf(&state, buf, CHUNK);
395 for (i = 0; t[i].name; i++) {
401 if (!(t[i].mask & test_mask))
405 * For first run, make sure CPUs are spun up and that
406 * we've touched the data.
410 t[i].fn(&t[i], buf, CHUNK);
413 fio_gettime(&ts, NULL);
414 t[i].fn(&t[i], buf, CHUNK);
415 usec = utime_since_now(&ts);
418 mb_sec = (double) mb / (double) usec;
419 mb_sec /= (1.024 * 1.024);
420 if (strlen(t[i].name) >= 7)
423 sprintf(pre, "\t\t");
424 printf("%s:%s%8.2f MiB/sec\n", t[i].name, pre, mb_sec);
426 printf("%s:inf MiB/sec\n", t[i].name);