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