blob: 368229e736bec8d9ef38c745c66bdd534363f66b [file] [log] [blame]
Jens Axboefec0f212014-02-07 14:39:33 -07001#include <stdio.h>
2#include <stdlib.h>
3#include <string.h>
4
5#include "../fio.h"
6#include "../gettime.h"
Danny Al-Gaaf9e529662014-04-30 20:48:16 +02007#include "../fio_time.h"
Jens Axboefec0f212014-02-07 14:39:33 -07008#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"
Elliott Hugheseda3a602017-05-19 18:53:02 -070019#include "../crc/sha3.h"
Jens Axboe844ea602014-02-20 13:21:45 -080020#include "../crc/xxhash.h"
Jens Axboeb0e1bb92014-09-27 09:30:56 -060021#include "../crc/murmur3.h"
Jens Axboe262cf5c2014-09-27 21:27:48 -060022#include "../crc/fnv.h"
Jens Axboe95a5a3f2014-09-27 09:29:42 -060023#include "../hash.h"
Jens Axboefec0f212014-02-07 14:39:33 -070024
Jens Axboeea1f1da2014-04-02 20:03:32 -060025#include "test.h"
26
Jens Axboef7540862014-02-07 20:52:32 -070027#define CHUNK 131072U
28#define NR_CHUNKS 2048U
Jens Axboefec0f212014-02-07 14:39:33 -070029
30struct test_type {
31 const char *name;
32 unsigned int mask;
Jens Axboe95a5a3f2014-09-27 09:29:42 -060033 void (*fn)(struct test_type *, void *, size_t);
34 uint32_t output;
Jens Axboefec0f212014-02-07 14:39:33 -070035};
36
37enum {
38 T_MD5 = 1U << 0,
39 T_CRC64 = 1U << 1,
40 T_CRC32 = 1U << 2,
41 T_CRC32C = 1U << 3,
42 T_CRC16 = 1U << 4,
43 T_CRC7 = 1U << 5,
44 T_SHA1 = 1U << 6,
45 T_SHA256 = 1U << 7,
46 T_SHA512 = 1U << 8,
Jens Axboe844ea602014-02-20 13:21:45 -080047 T_XXHASH = 1U << 9,
Jens Axboe67c1b7c2014-09-27 08:38:42 -060048 T_MURMUR3 = 1U << 10,
Jens Axboe95a5a3f2014-09-27 09:29:42 -060049 T_JHASH = 1U << 11,
Jens Axboe262cf5c2014-09-27 21:27:48 -060050 T_FNV = 1U << 12,
Elliott Hugheseda3a602017-05-19 18:53:02 -070051 T_SHA3_224 = 1U << 13,
52 T_SHA3_256 = 1U << 14,
53 T_SHA3_384 = 1U << 15,
54 T_SHA3_512 = 1U << 16,
Jens Axboefec0f212014-02-07 14:39:33 -070055};
56
Jens Axboe95a5a3f2014-09-27 09:29:42 -060057static void t_md5(struct test_type *t, void *buf, size_t size)
Jens Axboefec0f212014-02-07 14:39:33 -070058{
59 uint32_t digest[4];
60 struct fio_md5_ctx ctx = { .hash = digest };
Jens Axboefec0f212014-02-07 14:39:33 -070061 int i;
62
63 fio_md5_init(&ctx);
64
Jens Axboefc18c782014-09-27 14:13:58 -060065 for (i = 0; i < NR_CHUNKS; i++) {
Jens Axboe7e92c712014-07-25 10:12:26 +020066 fio_md5_update(&ctx, buf, size);
Jens Axboefc18c782014-09-27 14:13:58 -060067 fio_md5_final(&ctx);
68 }
Jens Axboe7e92c712014-07-25 10:12:26 +020069}
70
Jens Axboe95a5a3f2014-09-27 09:29:42 -060071static void t_crc64(struct test_type *t, void *buf, size_t size)
Jens Axboe7e92c712014-07-25 10:12:26 +020072{
Jens Axboe7e92c712014-07-25 10:12:26 +020073 int i;
Jens Axboefec0f212014-02-07 14:39:33 -070074
Jens Axboefec0f212014-02-07 14:39:33 -070075 for (i = 0; i < NR_CHUNKS; i++)
Elliott Hugheseda3a602017-05-19 18:53:02 -070076 t->output += fio_crc64(buf, size);
Jens Axboefec0f212014-02-07 14:39:33 -070077}
78
Jens Axboe95a5a3f2014-09-27 09:29:42 -060079static void t_crc32(struct test_type *t, void *buf, size_t size)
Jens Axboe7e92c712014-07-25 10:12:26 +020080{
Jens Axboe7e92c712014-07-25 10:12:26 +020081 int i;
82
Jens Axboe7e92c712014-07-25 10:12:26 +020083 for (i = 0; i < NR_CHUNKS; i++)
Elliott Hugheseda3a602017-05-19 18:53:02 -070084 t->output += fio_crc32(buf, size);
Jens Axboe7e92c712014-07-25 10:12:26 +020085}
86
Jens Axboe95a5a3f2014-09-27 09:29:42 -060087static void t_crc32c(struct test_type *t, void *buf, size_t size)
Jens Axboe7e92c712014-07-25 10:12:26 +020088{
Jens Axboe7e92c712014-07-25 10:12:26 +020089 int i;
90
Jens Axboe7e92c712014-07-25 10:12:26 +020091 for (i = 0; i < NR_CHUNKS; i++)
Elliott Hugheseda3a602017-05-19 18:53:02 -070092 t->output += fio_crc32c(buf, size);
Jens Axboe7e92c712014-07-25 10:12:26 +020093}
94
Jens Axboe95a5a3f2014-09-27 09:29:42 -060095static void t_crc16(struct test_type *t, void *buf, size_t size)
Jens Axboe7e92c712014-07-25 10:12:26 +020096{
Jens Axboe7e92c712014-07-25 10:12:26 +020097 int i;
98
Jens Axboe7e92c712014-07-25 10:12:26 +020099 for (i = 0; i < NR_CHUNKS; i++)
Elliott Hugheseda3a602017-05-19 18:53:02 -0700100 t->output += fio_crc16(buf, size);
Jens Axboe7e92c712014-07-25 10:12:26 +0200101}
102
Jens Axboe95a5a3f2014-09-27 09:29:42 -0600103static void t_crc7(struct test_type *t, void *buf, size_t size)
Jens Axboefec0f212014-02-07 14:39:33 -0700104{
Jens Axboefec0f212014-02-07 14:39:33 -0700105 int i;
106
Jens Axboefec0f212014-02-07 14:39:33 -0700107 for (i = 0; i < NR_CHUNKS; i++)
Elliott Hugheseda3a602017-05-19 18:53:02 -0700108 t->output += fio_crc7(buf, size);
Jens Axboefec0f212014-02-07 14:39:33 -0700109}
110
Jens Axboe95a5a3f2014-09-27 09:29:42 -0600111static void t_sha1(struct test_type *t, void *buf, size_t size)
Jens Axboefec0f212014-02-07 14:39:33 -0700112{
113 uint32_t sha[5];
114 struct fio_sha1_ctx ctx = { .H = sha };
Jens Axboefec0f212014-02-07 14:39:33 -0700115 int i;
116
117 fio_sha1_init(&ctx);
118
Jens Axboebf2d8162015-01-16 16:10:43 -0700119 for (i = 0; i < NR_CHUNKS; i++) {
Jens Axboe7e92c712014-07-25 10:12:26 +0200120 fio_sha1_update(&ctx, buf, size);
Jens Axboebf2d8162015-01-16 16:10:43 -0700121 fio_sha1_final(&ctx);
122 }
Jens Axboefec0f212014-02-07 14:39:33 -0700123}
124
Jens Axboe95a5a3f2014-09-27 09:29:42 -0600125static void t_sha256(struct test_type *t, void *buf, size_t size)
Jens Axboefec0f212014-02-07 14:39:33 -0700126{
127 uint8_t sha[64];
128 struct fio_sha256_ctx ctx = { .buf = sha };
Jens Axboefec0f212014-02-07 14:39:33 -0700129 int i;
130
131 fio_sha256_init(&ctx);
132
Jens Axboefc18c782014-09-27 14:13:58 -0600133 for (i = 0; i < NR_CHUNKS; i++) {
Jens Axboe7e92c712014-07-25 10:12:26 +0200134 fio_sha256_update(&ctx, buf, size);
Jens Axboefc18c782014-09-27 14:13:58 -0600135 fio_sha256_final(&ctx);
136 }
Jens Axboefec0f212014-02-07 14:39:33 -0700137}
138
Jens Axboe95a5a3f2014-09-27 09:29:42 -0600139static void t_sha512(struct test_type *t, void *buf, size_t size)
Jens Axboefec0f212014-02-07 14:39:33 -0700140{
141 uint8_t sha[128];
142 struct fio_sha512_ctx ctx = { .buf = sha };
Jens Axboefec0f212014-02-07 14:39:33 -0700143 int i;
144
145 fio_sha512_init(&ctx);
146
Jens Axboefec0f212014-02-07 14:39:33 -0700147 for (i = 0; i < NR_CHUNKS; i++)
Jens Axboe7e92c712014-07-25 10:12:26 +0200148 fio_sha512_update(&ctx, buf, size);
Jens Axboefec0f212014-02-07 14:39:33 -0700149}
150
Elliott Hugheseda3a602017-05-19 18:53:02 -0700151static void t_sha3_224(struct test_type *t, void *buf, size_t size)
152{
153 uint8_t sha[SHA3_224_DIGEST_SIZE];
154 struct fio_sha3_ctx ctx = { .sha = sha };
155 int i;
156
157 fio_sha3_224_init(&ctx);
158
159 for (i = 0; i < NR_CHUNKS; i++) {
160 fio_sha3_update(&ctx, buf, size);
161 fio_sha3_final(&ctx);
162 }
163}
164
165static void t_sha3_256(struct test_type *t, void *buf, size_t size)
166{
167 uint8_t sha[SHA3_256_DIGEST_SIZE];
168 struct fio_sha3_ctx ctx = { .sha = sha };
169 int i;
170
171 fio_sha3_256_init(&ctx);
172
173 for (i = 0; i < NR_CHUNKS; i++) {
174 fio_sha3_update(&ctx, buf, size);
175 fio_sha3_final(&ctx);
176 }
177}
178
179static void t_sha3_384(struct test_type *t, void *buf, size_t size)
180{
181 uint8_t sha[SHA3_384_DIGEST_SIZE];
182 struct fio_sha3_ctx ctx = { .sha = sha };
183 int i;
184
185 fio_sha3_384_init(&ctx);
186
187 for (i = 0; i < NR_CHUNKS; i++) {
188 fio_sha3_update(&ctx, buf, size);
189 fio_sha3_final(&ctx);
190 }
191}
192
193static void t_sha3_512(struct test_type *t, void *buf, size_t size)
194{
195 uint8_t sha[SHA3_512_DIGEST_SIZE];
196 struct fio_sha3_ctx ctx = { .sha = sha };
197 int i;
198
199 fio_sha3_512_init(&ctx);
200
201 for (i = 0; i < NR_CHUNKS; i++) {
202 fio_sha3_update(&ctx, buf, size);
203 fio_sha3_final(&ctx);
204 }
205}
206
Jens Axboe95a5a3f2014-09-27 09:29:42 -0600207static void t_murmur3(struct test_type *t, void *buf, size_t size)
Jens Axboe67c1b7c2014-09-27 08:38:42 -0600208{
209 int i;
210
211 for (i = 0; i < NR_CHUNKS; i++)
Elliott Hugheseda3a602017-05-19 18:53:02 -0700212 t->output += murmurhash3(buf, size, 0x8989);
Jens Axboe67c1b7c2014-09-27 08:38:42 -0600213}
214
Jens Axboe95a5a3f2014-09-27 09:29:42 -0600215static void t_jhash(struct test_type *t, void *buf, size_t size)
216{
217 int i;
218
219 for (i = 0; i < NR_CHUNKS; i++)
220 t->output += jhash(buf, size, 0x8989);
221}
222
Jens Axboe262cf5c2014-09-27 21:27:48 -0600223static void t_fnv(struct test_type *t, void *buf, size_t size)
224{
225 int i;
226
227 for (i = 0; i < NR_CHUNKS; i++)
228 t->output += fnv(buf, size, 0x8989);
229}
230
Jens Axboe95a5a3f2014-09-27 09:29:42 -0600231static void t_xxhash(struct test_type *t, void *buf, size_t size)
Jens Axboe844ea602014-02-20 13:21:45 -0800232{
233 void *state;
Jens Axboe844ea602014-02-20 13:21:45 -0800234 int i;
235
236 state = XXH32_init(0x8989);
237
Jens Axboe844ea602014-02-20 13:21:45 -0800238 for (i = 0; i < NR_CHUNKS; i++)
Jens Axboe7e92c712014-07-25 10:12:26 +0200239 XXH32_update(state, buf, size);
Jens Axboe844ea602014-02-20 13:21:45 -0800240
Jens Axboe95a5a3f2014-09-27 09:29:42 -0600241 t->output = XXH32_digest(state);
Jens Axboe844ea602014-02-20 13:21:45 -0800242}
243
Jens Axboefec0f212014-02-07 14:39:33 -0700244static struct test_type t[] = {
245 {
246 .name = "md5",
247 .mask = T_MD5,
248 .fn = t_md5,
249 },
250 {
251 .name = "crc64",
252 .mask = T_CRC64,
253 .fn = t_crc64,
254 },
255 {
256 .name = "crc32",
257 .mask = T_CRC32,
258 .fn = t_crc32,
259 },
260 {
261 .name = "crc32c",
262 .mask = T_CRC32C,
263 .fn = t_crc32c,
264 },
265 {
266 .name = "crc16",
267 .mask = T_CRC16,
268 .fn = t_crc16,
269 },
270 {
271 .name = "crc7",
272 .mask = T_CRC7,
273 .fn = t_crc7,
274 },
275 {
276 .name = "sha1",
277 .mask = T_SHA1,
278 .fn = t_sha1,
279 },
280 {
281 .name = "sha256",
282 .mask = T_SHA256,
283 .fn = t_sha256,
284 },
285 {
286 .name = "sha512",
287 .mask = T_SHA512,
288 .fn = t_sha512,
289 },
290 {
Jens Axboe844ea602014-02-20 13:21:45 -0800291 .name = "xxhash",
292 .mask = T_XXHASH,
293 .fn = t_xxhash,
294 },
295 {
Jens Axboe67c1b7c2014-09-27 08:38:42 -0600296 .name = "murmur3",
297 .mask = T_MURMUR3,
298 .fn = t_murmur3,
299 },
300 {
Jens Axboe95a5a3f2014-09-27 09:29:42 -0600301 .name = "jhash",
302 .mask = T_JHASH,
303 .fn = t_jhash,
304 },
305 {
Jens Axboe262cf5c2014-09-27 21:27:48 -0600306 .name = "fnv",
307 .mask = T_FNV,
308 .fn = t_fnv,
309 },
310 {
Elliott Hugheseda3a602017-05-19 18:53:02 -0700311 .name = "sha3-224",
312 .mask = T_SHA3_224,
313 .fn = t_sha3_224,
314 },
315 {
316 .name = "sha3-256",
317 .mask = T_SHA3_256,
318 .fn = t_sha3_256,
319 },
320 {
321 .name = "sha3-384",
322 .mask = T_SHA3_384,
323 .fn = t_sha3_384,
324 },
325 {
326 .name = "sha3-512",
327 .mask = T_SHA3_512,
328 .fn = t_sha3_512,
329 },
330 {
Jens Axboefec0f212014-02-07 14:39:33 -0700331 .name = NULL,
332 },
333};
334
335static unsigned int get_test_mask(const char *type)
336{
337 char *ostr, *str = strdup(type);
338 unsigned int mask;
339 char *name;
340 int i;
341
342 ostr = str;
343 mask = 0;
344 while ((name = strsep(&str, ",")) != NULL) {
345 for (i = 0; t[i].name; i++) {
Jens Axboef7540862014-02-07 20:52:32 -0700346 if (!strcmp(t[i].name, name)) {
Jens Axboefec0f212014-02-07 14:39:33 -0700347 mask |= t[i].mask;
348 break;
349 }
350 }
351 }
352
353 free(ostr);
354 return mask;
355}
356
Jens Axboe782744e2014-02-07 20:54:39 -0700357static int list_types(void)
358{
359 int i;
360
361 for (i = 0; t[i].name; i++)
362 printf("%s\n", t[i].name);
363
Jens Axboe7e92c712014-07-25 10:12:26 +0200364 return 1;
Jens Axboe782744e2014-02-07 20:54:39 -0700365}
366
Jens Axboefec0f212014-02-07 14:39:33 -0700367int fio_crctest(const char *type)
368{
369 unsigned int test_mask = 0;
370 uint64_t mb = CHUNK * NR_CHUNKS;
Jens Axboef8889712014-07-25 15:15:46 +0200371 struct frand_state state;
Jens Axboe7e92c712014-07-25 10:12:26 +0200372 int i, first = 1;
373 void *buf;
Jens Axboefec0f212014-02-07 14:39:33 -0700374
Elliott Hugheseda3a602017-05-19 18:53:02 -0700375 crc32c_arm64_probe();
Jens Axboefec0f212014-02-07 14:39:33 -0700376 crc32c_intel_probe();
377
378 if (!type)
379 test_mask = ~0U;
Jens Axboe782744e2014-02-07 20:54:39 -0700380 else if (!strcmp(type, "help") || !strcmp(type, "list"))
381 return list_types();
Jens Axboefec0f212014-02-07 14:39:33 -0700382 else
383 test_mask = get_test_mask(type);
384
Jens Axboe7e92c712014-07-25 10:12:26 +0200385 if (!test_mask) {
386 fprintf(stderr, "fio: unknown hash `%s`. Available:\n", type);
387 return list_types();
388 }
389
390 buf = malloc(CHUNK);
Elliott Hugheseda3a602017-05-19 18:53:02 -0700391 init_rand_seed(&state, 0x8989, 0);
Jens Axboef8889712014-07-25 15:15:46 +0200392 fill_random_buf(&state, buf, CHUNK);
Jens Axboe7e92c712014-07-25 10:12:26 +0200393
Jens Axboefec0f212014-02-07 14:39:33 -0700394 for (i = 0; t[i].name; i++) {
Jens Axboef8889712014-07-25 15:15:46 +0200395 struct timeval tv;
Jens Axboefec0f212014-02-07 14:39:33 -0700396 double mb_sec;
397 uint64_t usec;
Jens Axboe3e6d4152014-09-27 08:43:27 -0600398 char pre[3];
Jens Axboefec0f212014-02-07 14:39:33 -0700399
400 if (!(t[i].mask & test_mask))
401 continue;
402
Jens Axboef8889712014-07-25 15:15:46 +0200403 /*
404 * For first run, make sure CPUs are spun up and that
405 * we've touched the data.
406 */
407 if (first) {
408 usec_spin(100000);
Jens Axboe95a5a3f2014-09-27 09:29:42 -0600409 t[i].fn(&t[i], buf, CHUNK);
Jens Axboef8889712014-07-25 15:15:46 +0200410 }
411
412 fio_gettime(&tv, NULL);
Jens Axboe95a5a3f2014-09-27 09:29:42 -0600413 t[i].fn(&t[i], buf, CHUNK);
Jens Axboef8889712014-07-25 15:15:46 +0200414 usec = utime_since_now(&tv);
Jens Axboe7e92c712014-07-25 10:12:26 +0200415
Jens Axboe7b3aea92014-10-14 19:47:41 -0600416 if (usec) {
417 mb_sec = (double) mb / (double) usec;
418 mb_sec /= (1.024 * 1.024);
419 if (strlen(t[i].name) >= 7)
420 sprintf(pre, "\t");
421 else
422 sprintf(pre, "\t\t");
Elliott Hugheseda3a602017-05-19 18:53:02 -0700423 printf("%s:%s%8.2f MiB/sec\n", t[i].name, pre, mb_sec);
Jens Axboe7b3aea92014-10-14 19:47:41 -0600424 } else
Elliott Hugheseda3a602017-05-19 18:53:02 -0700425 printf("%s:inf MiB/sec\n", t[i].name);
Jens Axboe7e92c712014-07-25 10:12:26 +0200426 first = 0;
Jens Axboefec0f212014-02-07 14:39:33 -0700427 }
Jens Axboe782744e2014-02-07 20:54:39 -0700428
Jens Axboe7e92c712014-07-25 10:12:26 +0200429 free(buf);
Jens Axboefec0f212014-02-07 14:39:33 -0700430 return 0;
431}