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/xxhash.h"
20 #include "../crc/murmur3.h"
21 #include "../crc/fnv.h"
27 #define NR_CHUNKS 2048U
32 void (*fn)(struct test_type *, void *, size_t);
52 static void t_md5(struct test_type *t, void *buf, size_t size)
55 struct fio_md5_ctx ctx = { .hash = digest };
60 for (i = 0; i < NR_CHUNKS; i++) {
61 fio_md5_update(&ctx, buf, size);
66 static void t_crc64(struct test_type *t, void *buf, size_t size)
70 for (i = 0; i < NR_CHUNKS; i++)
74 static void t_crc32(struct test_type *t, void *buf, size_t size)
78 for (i = 0; i < NR_CHUNKS; i++)
82 static void t_crc32c(struct test_type *t, void *buf, size_t size)
86 for (i = 0; i < NR_CHUNKS; i++)
87 fio_crc32c(buf, size);
90 static void t_crc16(struct test_type *t, void *buf, size_t size)
94 for (i = 0; i < NR_CHUNKS; i++)
98 static void t_crc7(struct test_type *t, void *buf, size_t size)
102 for (i = 0; i < NR_CHUNKS; i++)
106 static void t_sha1(struct test_type *t, void *buf, size_t size)
109 struct fio_sha1_ctx ctx = { .H = sha };
114 for (i = 0; i < NR_CHUNKS; i++)
115 fio_sha1_update(&ctx, buf, size);
118 static void t_sha256(struct test_type *t, void *buf, size_t size)
121 struct fio_sha256_ctx ctx = { .buf = sha };
124 fio_sha256_init(&ctx);
126 for (i = 0; i < NR_CHUNKS; i++) {
127 fio_sha256_update(&ctx, buf, size);
128 fio_sha256_final(&ctx);
132 static void t_sha512(struct test_type *t, void *buf, size_t size)
135 struct fio_sha512_ctx ctx = { .buf = sha };
138 fio_sha512_init(&ctx);
140 for (i = 0; i < NR_CHUNKS; i++)
141 fio_sha512_update(&ctx, buf, size);
144 static void t_murmur3(struct test_type *t, void *buf, size_t size)
148 for (i = 0; i < NR_CHUNKS; i++)
149 murmurhash3(buf, size, 0x8989);
152 static void t_jhash(struct test_type *t, void *buf, size_t size)
156 for (i = 0; i < NR_CHUNKS; i++)
157 t->output += jhash(buf, size, 0x8989);
160 static void t_fnv(struct test_type *t, void *buf, size_t size)
164 for (i = 0; i < NR_CHUNKS; i++)
165 t->output += fnv(buf, size, 0x8989);
168 static void t_xxhash(struct test_type *t, void *buf, size_t size)
173 state = XXH32_init(0x8989);
175 for (i = 0; i < NR_CHUNKS; i++)
176 XXH32_update(state, buf, size);
178 t->output = XXH32_digest(state);
181 static struct test_type t[] = {
252 static unsigned int get_test_mask(const char *type)
254 char *ostr, *str = strdup(type);
261 while ((name = strsep(&str, ",")) != NULL) {
262 for (i = 0; t[i].name; i++) {
263 if (!strcmp(t[i].name, name)) {
274 static int list_types(void)
278 for (i = 0; t[i].name; i++)
279 printf("%s\n", t[i].name);
284 int fio_crctest(const char *type)
286 unsigned int test_mask = 0;
287 uint64_t mb = CHUNK * NR_CHUNKS;
288 struct frand_state state;
292 crc32c_intel_probe();
296 else if (!strcmp(type, "help") || !strcmp(type, "list"))
299 test_mask = get_test_mask(type);
302 fprintf(stderr, "fio: unknown hash `%s`. Available:\n", type);
307 init_rand_seed(&state, 0x8989);
308 fill_random_buf(&state, buf, CHUNK);
310 for (i = 0; t[i].name; i++) {
316 if (!(t[i].mask & test_mask))
320 * For first run, make sure CPUs are spun up and that
321 * we've touched the data.
325 t[i].fn(&t[i], buf, CHUNK);
328 fio_gettime(&tv, NULL);
329 t[i].fn(&t[i], buf, CHUNK);
330 usec = utime_since_now(&tv);
333 mb_sec = (double) mb / (double) usec;
334 mb_sec /= (1.024 * 1.024);
335 if (strlen(t[i].name) >= 7)
338 sprintf(pre, "\t\t");
339 printf("%s:%s%8.2f MB/sec\n", t[i].name, pre, mb_sec);
341 printf("%s:inf MB/sec\n", t[i].name);