6 #include "../gettime.h"
7 #include "../fio_time.h"
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"
19 #include "../crc/sha3.h"
20 #include "../crc/xxhash.h"
21 #include "../crc/murmur3.h"
22 #include "../crc/fnv.h"
28 #define NR_CHUNKS 2048U
33 void (*fn)(struct test_type *, void *, size_t);
51 T_SHA3_224 = 1U << 13,
52 T_SHA3_256 = 1U << 14,
53 T_SHA3_384 = 1U << 15,
54 T_SHA3_512 = 1U << 16,
57 static void t_md5(struct test_type *t, void *buf, size_t size)
60 struct fio_md5_ctx ctx = { .hash = digest };
65 for (i = 0; i < NR_CHUNKS; i++) {
66 fio_md5_update(&ctx, buf, size);
71 static void t_crc64(struct test_type *t, void *buf, size_t size)
75 for (i = 0; i < NR_CHUNKS; i++)
76 t->output += fio_crc64(buf, size);
79 static void t_crc32(struct test_type *t, void *buf, size_t size)
83 for (i = 0; i < NR_CHUNKS; i++)
84 t->output += fio_crc32(buf, size);
87 static void t_crc32c(struct test_type *t, void *buf, size_t size)
91 for (i = 0; i < NR_CHUNKS; i++)
92 t->output += fio_crc32c(buf, size);
95 static void t_crc16(struct test_type *t, void *buf, size_t size)
99 for (i = 0; i < NR_CHUNKS; i++)
100 t->output += fio_crc16(buf, size);
103 static void t_crc7(struct test_type *t, void *buf, size_t size)
107 for (i = 0; i < NR_CHUNKS; i++)
108 t->output += fio_crc7(buf, size);
111 static void t_sha1(struct test_type *t, void *buf, size_t size)
114 struct fio_sha1_ctx ctx = { .H = sha };
119 for (i = 0; i < NR_CHUNKS; i++) {
120 fio_sha1_update(&ctx, buf, size);
121 fio_sha1_final(&ctx);
125 static void t_sha256(struct test_type *t, void *buf, size_t size)
128 struct fio_sha256_ctx ctx = { .buf = sha };
131 fio_sha256_init(&ctx);
133 for (i = 0; i < NR_CHUNKS; i++) {
134 fio_sha256_update(&ctx, buf, size);
135 fio_sha256_final(&ctx);
139 static void t_sha512(struct test_type *t, void *buf, size_t size)
142 struct fio_sha512_ctx ctx = { .buf = sha };
145 fio_sha512_init(&ctx);
147 for (i = 0; i < NR_CHUNKS; i++)
148 fio_sha512_update(&ctx, buf, size);
151 static void t_sha3_224(struct test_type *t, void *buf, size_t size)
153 uint8_t sha[SHA3_224_DIGEST_SIZE];
154 struct fio_sha3_ctx ctx = { .sha = sha };
157 fio_sha3_224_init(&ctx);
159 for (i = 0; i < NR_CHUNKS; i++) {
160 fio_sha3_update(&ctx, buf, size);
161 fio_sha3_final(&ctx);
165 static void t_sha3_256(struct test_type *t, void *buf, size_t size)
167 uint8_t sha[SHA3_256_DIGEST_SIZE];
168 struct fio_sha3_ctx ctx = { .sha = sha };
171 fio_sha3_256_init(&ctx);
173 for (i = 0; i < NR_CHUNKS; i++) {
174 fio_sha3_update(&ctx, buf, size);
175 fio_sha3_final(&ctx);
179 static void t_sha3_384(struct test_type *t, void *buf, size_t size)
181 uint8_t sha[SHA3_384_DIGEST_SIZE];
182 struct fio_sha3_ctx ctx = { .sha = sha };
185 fio_sha3_384_init(&ctx);
187 for (i = 0; i < NR_CHUNKS; i++) {
188 fio_sha3_update(&ctx, buf, size);
189 fio_sha3_final(&ctx);
193 static void t_sha3_512(struct test_type *t, void *buf, size_t size)
195 uint8_t sha[SHA3_512_DIGEST_SIZE];
196 struct fio_sha3_ctx ctx = { .sha = sha };
199 fio_sha3_512_init(&ctx);
201 for (i = 0; i < NR_CHUNKS; i++) {
202 fio_sha3_update(&ctx, buf, size);
203 fio_sha3_final(&ctx);
207 static void t_murmur3(struct test_type *t, void *buf, size_t size)
211 for (i = 0; i < NR_CHUNKS; i++)
212 t->output += murmurhash3(buf, size, 0x8989);
215 static void t_jhash(struct test_type *t, void *buf, size_t size)
219 for (i = 0; i < NR_CHUNKS; i++)
220 t->output += jhash(buf, size, 0x8989);
223 static void t_fnv(struct test_type *t, void *buf, size_t size)
227 for (i = 0; i < NR_CHUNKS; i++)
228 t->output += fnv(buf, size, 0x8989);
231 static void t_xxhash(struct test_type *t, void *buf, size_t size)
236 state = XXH32_init(0x8989);
238 for (i = 0; i < NR_CHUNKS; i++)
239 XXH32_update(state, buf, size);
241 t->output = XXH32_digest(state);
244 static struct test_type t[] = {
335 static unsigned int get_test_mask(const char *type)
337 char *ostr, *str = strdup(type);
344 while ((name = strsep(&str, ",")) != NULL) {
345 for (i = 0; t[i].name; i++) {
346 if (!strcmp(t[i].name, name)) {
357 static int list_types(void)
361 for (i = 0; t[i].name; i++)
362 printf("%s\n", t[i].name);
367 int fio_crctest(const char *type)
369 unsigned int test_mask = 0;
370 uint64_t mb = CHUNK * NR_CHUNKS;
371 struct frand_state state;
375 crc32c_arm64_probe();
376 crc32c_intel_probe();
380 else if (!strcmp(type, "help") || !strcmp(type, "list"))
383 test_mask = get_test_mask(type);
386 fprintf(stderr, "fio: unknown hash `%s`. Available:\n", type);
391 init_rand_seed(&state, 0x8989, 0);
392 fill_random_buf(&state, buf, CHUNK);
394 for (i = 0; t[i].name; i++) {
400 if (!(t[i].mask & test_mask))
404 * For first run, make sure CPUs are spun up and that
405 * we've touched the data.
409 t[i].fn(&t[i], buf, CHUNK);
412 fio_gettime(&ts, NULL);
413 t[i].fn(&t[i], buf, CHUNK);
414 usec = utime_since_now(&ts);
417 mb_sec = (double) mb / (double) usec;
418 mb_sec /= (1.024 * 1.024);
419 if (strlen(t[i].name) >= 7)
422 sprintf(pre, "\t\t");
423 printf("%s:%s%8.2f MiB/sec\n", t[i].name, pre, mb_sec);
425 printf("%s:inf MiB/sec\n", t[i].name);