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);
116 fio_sha1_final(&ctx);
120 static void t_sha256(struct test_type *t, void *buf, size_t size)
123 struct fio_sha256_ctx ctx = { .buf = sha };
126 fio_sha256_init(&ctx);
128 for (i = 0; i < NR_CHUNKS; i++) {
129 fio_sha256_update(&ctx, buf, size);
130 fio_sha256_final(&ctx);
134 static void t_sha512(struct test_type *t, void *buf, size_t size)
137 struct fio_sha512_ctx ctx = { .buf = sha };
140 fio_sha512_init(&ctx);
142 for (i = 0; i < NR_CHUNKS; i++)
143 fio_sha512_update(&ctx, buf, size);
146 static void t_murmur3(struct test_type *t, void *buf, size_t size)
150 for (i = 0; i < NR_CHUNKS; i++)
151 murmurhash3(buf, size, 0x8989);
154 static void t_jhash(struct test_type *t, void *buf, size_t size)
158 for (i = 0; i < NR_CHUNKS; i++)
159 t->output += jhash(buf, size, 0x8989);
162 static void t_fnv(struct test_type *t, void *buf, size_t size)
166 for (i = 0; i < NR_CHUNKS; i++)
167 t->output += fnv(buf, size, 0x8989);
170 static void t_xxhash(struct test_type *t, void *buf, size_t size)
175 state = XXH32_init(0x8989);
177 for (i = 0; i < NR_CHUNKS; i++)
178 XXH32_update(state, buf, size);
180 t->output = XXH32_digest(state);
183 static struct test_type t[] = {
254 static unsigned int get_test_mask(const char *type)
256 char *ostr, *str = strdup(type);
263 while ((name = strsep(&str, ",")) != NULL) {
264 for (i = 0; t[i].name; i++) {
265 if (!strcmp(t[i].name, name)) {
276 static int list_types(void)
280 for (i = 0; t[i].name; i++)
281 printf("%s\n", t[i].name);
286 int fio_crctest(const char *type)
288 unsigned int test_mask = 0;
289 uint64_t mb = CHUNK * NR_CHUNKS;
290 struct frand_state state;
294 crc32c_intel_probe();
298 else if (!strcmp(type, "help") || !strcmp(type, "list"))
301 test_mask = get_test_mask(type);
304 fprintf(stderr, "fio: unknown hash `%s`. Available:\n", type);
309 init_rand_seed(&state, 0x8989, 0);
310 fill_random_buf(&state, buf, CHUNK);
312 for (i = 0; t[i].name; i++) {
318 if (!(t[i].mask & test_mask))
322 * For first run, make sure CPUs are spun up and that
323 * we've touched the data.
327 t[i].fn(&t[i], buf, CHUNK);
330 fio_gettime(&tv, NULL);
331 t[i].fn(&t[i], buf, CHUNK);
332 usec = utime_since_now(&tv);
335 mb_sec = (double) mb / (double) usec;
336 mb_sec /= (1.024 * 1.024);
337 if (strlen(t[i].name) >= 7)
340 sprintf(pre, "\t\t");
341 printf("%s:%s%8.2f MB/sec\n", t[i].name, pre, mb_sec);
343 printf("%s:inf MB/sec\n", t[i].name);