Add support for the Google xxhash checksumming function
[fio.git] / crc / test.c
CommitLineData
fec0f21c
JA
1#include <stdio.h>
2#include <stdlib.h>
3#include <string.h>
4
5#include "../fio.h"
6#include "../gettime.h"
7#include "../time.h"
8#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"
844ea602 19#include "../crc/xxhash.h"
fec0f21c 20
f7540869
JA
21#define CHUNK 131072U
22#define NR_CHUNKS 2048U
fec0f21c
JA
23
24struct test_type {
25 const char *name;
26 unsigned int mask;
27 uint64_t (*fn)(void);
28};
29
30enum {
31 T_MD5 = 1U << 0,
32 T_CRC64 = 1U << 1,
33 T_CRC32 = 1U << 2,
34 T_CRC32C = 1U << 3,
35 T_CRC16 = 1U << 4,
36 T_CRC7 = 1U << 5,
37 T_SHA1 = 1U << 6,
38 T_SHA256 = 1U << 7,
39 T_SHA512 = 1U << 8,
844ea602 40 T_XXHASH = 1U << 9,
fec0f21c
JA
41};
42
43static void randomize_buf(void *buf, unsigned int size, int seed)
44{
45 struct frand_state state;
46
47 init_rand_seed(&state, seed);
48 fill_random_buf(&state, buf, size);
49}
50
51static uint64_t t_md5(void)
52{
53 uint32_t digest[4];
54 struct fio_md5_ctx ctx = { .hash = digest };
55 struct timeval s;
56 uint64_t ret;
57 void *buf;
58 int i;
59
60 fio_md5_init(&ctx);
61
62 buf = malloc(CHUNK);
63 randomize_buf(buf, CHUNK, 0x8989);
64
65 fio_gettime(&s, NULL);
66 for (i = 0; i < NR_CHUNKS; i++)
67 fio_md5_update(&ctx, buf, CHUNK);
68
69 ret = utime_since_now(&s);
70 free(buf);
71 return ret;
72}
73
74static uint64_t t_crc64(void)
75{
76 struct timeval s;
77 uint64_t ret;
78 void *buf;
79 int i;
80
81 buf = malloc(CHUNK);
82 randomize_buf(buf, CHUNK, 0x8989);
83
84 fio_gettime(&s, NULL);
85 for (i = 0; i < NR_CHUNKS; i++)
86 fio_crc64(buf, CHUNK);
87
88 ret = utime_since_now(&s);
89 free(buf);
90 return ret;
91}
92
93static uint64_t t_crc32(void)
94{
95 struct timeval s;
96 uint64_t ret;
97 void *buf;
98 int i;
99
100 buf = malloc(CHUNK);
101 randomize_buf(buf, CHUNK, 0x8989);
102
103 fio_gettime(&s, NULL);
104 for (i = 0; i < NR_CHUNKS; i++)
105 fio_crc32(buf, CHUNK);
106
107 ret = utime_since_now(&s);
108 free(buf);
109 return ret;
110}
111
112static uint64_t t_crc32c(void)
113{
114 struct timeval s;
115 uint64_t ret;
116 void *buf;
117 int i;
118
119 buf = malloc(CHUNK);
120 randomize_buf(buf, CHUNK, 0x8989);
121
122 fio_gettime(&s, NULL);
123 for (i = 0; i < NR_CHUNKS; i++)
124 fio_crc32c(buf, CHUNK);
125
126 ret = utime_since_now(&s);
127 free(buf);
128 return ret;
129}
130
131static uint64_t t_crc16(void)
132{
133 struct timeval s;
134 uint64_t ret;
135 void *buf;
136 int i;
137
138 buf = malloc(CHUNK);
139 randomize_buf(buf, CHUNK, 0x8989);
140
141 fio_gettime(&s, NULL);
142 for (i = 0; i < NR_CHUNKS; i++)
143 fio_crc16(buf, CHUNK);
144
145 ret = utime_since_now(&s);
146 free(buf);
147 return ret;
148}
149
150static uint64_t t_crc7(void)
151{
152 struct timeval s;
153 uint64_t ret;
154 void *buf;
155 int i;
156
157 buf = malloc(CHUNK);
158 randomize_buf(buf, CHUNK, 0x8989);
159
160 fio_gettime(&s, NULL);
161 for (i = 0; i < NR_CHUNKS; i++)
162 fio_crc7(buf, CHUNK);
163
164 ret = utime_since_now(&s);
165 free(buf);
166 return ret;
167}
168
169static uint64_t t_sha1(void)
170{
171 uint32_t sha[5];
172 struct fio_sha1_ctx ctx = { .H = sha };
173 struct timeval s;
174 uint64_t ret;
175 void *buf;
176 int i;
177
178 fio_sha1_init(&ctx);
179
180 buf = malloc(CHUNK);
181 randomize_buf(buf, CHUNK, 0x8989);
182
183 fio_gettime(&s, NULL);
184 for (i = 0; i < NR_CHUNKS; i++)
185 fio_sha1_update(&ctx, buf, CHUNK);
186
187 ret = utime_since_now(&s);
188 free(buf);
189 return ret;
190}
191
192static uint64_t t_sha256(void)
193{
194 uint8_t sha[64];
195 struct fio_sha256_ctx ctx = { .buf = sha };
196 struct timeval s;
197 uint64_t ret;
198 void *buf;
199 int i;
200
201 fio_sha256_init(&ctx);
202
203 buf = malloc(CHUNK);
204 randomize_buf(buf, CHUNK, 0x8989);
205
206 fio_gettime(&s, NULL);
207 for (i = 0; i < NR_CHUNKS; i++)
208 fio_sha256_update(&ctx, buf, CHUNK);
209
210 ret = utime_since_now(&s);
211 free(buf);
212 return ret;
213}
214
215static uint64_t t_sha512(void)
216{
217 uint8_t sha[128];
218 struct fio_sha512_ctx ctx = { .buf = sha };
219 struct timeval s;
220 uint64_t ret;
221 void *buf;
222 int i;
223
224 fio_sha512_init(&ctx);
225
226 buf = malloc(CHUNK);
227 randomize_buf(buf, CHUNK, 0x8989);
228
229 fio_gettime(&s, NULL);
230 for (i = 0; i < NR_CHUNKS; i++)
231 fio_sha512_update(&ctx, buf, CHUNK);
232
233 ret = utime_since_now(&s);
234 free(buf);
235 return ret;
236}
237
844ea602
JA
238static uint64_t t_xxhash(void)
239{
240 void *state;
241 struct timeval s;
242 uint64_t ret;
243 void *buf;
244 int i;
245
246 state = XXH32_init(0x8989);
247
248 buf = malloc(CHUNK);
249 randomize_buf(buf, CHUNK, 0x8989);
250
251 fio_gettime(&s, NULL);
252 for (i = 0; i < NR_CHUNKS; i++)
253 XXH32_update(state, buf, CHUNK);
254
255 XXH32_digest(state);
256 ret = utime_since_now(&s);
257 free(buf);
258 return ret;
259}
260
fec0f21c
JA
261static struct test_type t[] = {
262 {
263 .name = "md5",
264 .mask = T_MD5,
265 .fn = t_md5,
266 },
267 {
268 .name = "crc64",
269 .mask = T_CRC64,
270 .fn = t_crc64,
271 },
272 {
273 .name = "crc32",
274 .mask = T_CRC32,
275 .fn = t_crc32,
276 },
277 {
278 .name = "crc32c",
279 .mask = T_CRC32C,
280 .fn = t_crc32c,
281 },
282 {
283 .name = "crc16",
284 .mask = T_CRC16,
285 .fn = t_crc16,
286 },
287 {
288 .name = "crc7",
289 .mask = T_CRC7,
290 .fn = t_crc7,
291 },
292 {
293 .name = "sha1",
294 .mask = T_SHA1,
295 .fn = t_sha1,
296 },
297 {
298 .name = "sha256",
299 .mask = T_SHA256,
300 .fn = t_sha256,
301 },
302 {
303 .name = "sha512",
304 .mask = T_SHA512,
305 .fn = t_sha512,
306 },
844ea602
JA
307 {
308 .name = "xxhash",
309 .mask = T_XXHASH,
310 .fn = t_xxhash,
311 },
fec0f21c
JA
312 {
313 .name = NULL,
314 },
315};
316
317static unsigned int get_test_mask(const char *type)
318{
319 char *ostr, *str = strdup(type);
320 unsigned int mask;
321 char *name;
322 int i;
323
324 ostr = str;
325 mask = 0;
326 while ((name = strsep(&str, ",")) != NULL) {
327 for (i = 0; t[i].name; i++) {
f7540869 328 if (!strcmp(t[i].name, name)) {
fec0f21c
JA
329 mask |= t[i].mask;
330 break;
331 }
332 }
333 }
334
335 free(ostr);
336 return mask;
337}
338
782744ef
JA
339static int list_types(void)
340{
341 int i;
342
343 for (i = 0; t[i].name; i++)
344 printf("%s\n", t[i].name);
345
346 return 0;
347}
348
fec0f21c
JA
349int fio_crctest(const char *type)
350{
351 unsigned int test_mask = 0;
352 uint64_t mb = CHUNK * NR_CHUNKS;
353 int i;
354
355 crc32c_intel_probe();
356
357 if (!type)
358 test_mask = ~0U;
782744ef
JA
359 else if (!strcmp(type, "help") || !strcmp(type, "list"))
360 return list_types();
fec0f21c
JA
361 else
362 test_mask = get_test_mask(type);
363
364 for (i = 0; t[i].name; i++) {
365 double mb_sec;
366 uint64_t usec;
367
368 if (!(t[i].mask & test_mask))
369 continue;
370
371 usec = t[i].fn();
372 mb_sec = (double) mb / (double) usec;
373 mb_sec /= (1.024 * 1.024);
374 printf("%s:\t%.2f MB/sec\n", t[i].name, mb_sec);
375 }
782744ef 376
fec0f21c
JA
377 return 0;
378}