rocker: Tweak stubbed out monitor commands' error messages
[qemu/armbru.git] / tests / bench / xbzrle-bench.c
blob8848a3a32d7ef591f8eae2cbbc898f92af07f549
1 /*
2 * Xor Based Zero Run Length Encoding unit tests.
4 * Copyright 2013 Red Hat, Inc. and/or its affiliates
6 * Authors:
7 * Orit Wasserman <owasserm@redhat.com>
9 * This work is licensed under the terms of the GNU GPL, version 2 or later.
10 * See the COPYING file in the top-level directory.
13 #include "qemu/osdep.h"
14 #include "qemu/cutils.h"
15 #include "../migration/xbzrle.h"
17 #if defined(CONFIG_AVX512BW_OPT)
18 #define XBZRLE_PAGE_SIZE 4096
19 static bool is_cpu_support_avx512bw;
20 #include "qemu/cpuid.h"
21 static void __attribute__((constructor)) init_cpu_flag(void)
23 unsigned max = __get_cpuid_max(0, NULL);
24 int a, b, c, d;
25 is_cpu_support_avx512bw = false;
26 if (max >= 1) {
27 __cpuid(1, a, b, c, d);
28 /* We must check that AVX is not just available, but usable. */
29 if ((c & bit_OSXSAVE) && (c & bit_AVX) && max >= 7) {
30 int bv;
31 __asm("xgetbv" : "=a"(bv), "=d"(d) : "c"(0));
32 __cpuid_count(7, 0, a, b, c, d);
33 /* 0xe6:
34 * XCR0[7:5] = 111b (OPMASK state, upper 256-bit of ZMM0-ZMM15
35 * and ZMM16-ZMM31 state are enabled by OS)
36 * XCR0[2:1] = 11b (XMM state and YMM state are enabled by OS)
38 if ((bv & 0xe6) == 0xe6 && (b & bit_AVX512BW)) {
39 is_cpu_support_avx512bw = true;
43 return ;
46 struct ResTime {
47 float t_raw;
48 float t_512;
52 /* Function prototypes
53 int xbzrle_encode_buffer_avx512(uint8_t *old_buf, uint8_t *new_buf, int slen,
54 uint8_t *dst, int dlen);
56 static void encode_decode_zero(struct ResTime *res)
58 uint8_t *buffer = g_malloc0(XBZRLE_PAGE_SIZE);
59 uint8_t *compressed = g_malloc0(XBZRLE_PAGE_SIZE);
60 uint8_t *buffer512 = g_malloc0(XBZRLE_PAGE_SIZE);
61 uint8_t *compressed512 = g_malloc0(XBZRLE_PAGE_SIZE);
62 int i = 0;
63 int dlen = 0, dlen512 = 0;
64 int diff_len = g_test_rand_int_range(0, XBZRLE_PAGE_SIZE - 1006);
66 for (i = diff_len; i > 0; i--) {
67 buffer[1000 + i] = i;
68 buffer512[1000 + i] = i;
71 buffer[1000 + diff_len + 3] = 103;
72 buffer[1000 + diff_len + 5] = 105;
74 buffer512[1000 + diff_len + 3] = 103;
75 buffer512[1000 + diff_len + 5] = 105;
77 /* encode zero page */
78 time_t t_start, t_end, t_start512, t_end512;
79 t_start = clock();
80 dlen = xbzrle_encode_buffer(buffer, buffer, XBZRLE_PAGE_SIZE, compressed,
81 XBZRLE_PAGE_SIZE);
82 t_end = clock();
83 float time_val = difftime(t_end, t_start);
84 g_assert(dlen == 0);
86 t_start512 = clock();
87 dlen512 = xbzrle_encode_buffer_avx512(buffer512, buffer512, XBZRLE_PAGE_SIZE,
88 compressed512, XBZRLE_PAGE_SIZE);
89 t_end512 = clock();
90 float time_val512 = difftime(t_end512, t_start512);
91 g_assert(dlen512 == 0);
93 res->t_raw = time_val;
94 res->t_512 = time_val512;
96 g_free(buffer);
97 g_free(compressed);
98 g_free(buffer512);
99 g_free(compressed512);
103 static void test_encode_decode_zero_avx512(void)
105 int i;
106 float time_raw = 0.0, time_512 = 0.0;
107 struct ResTime res;
108 for (i = 0; i < 10000; i++) {
109 encode_decode_zero(&res);
110 time_raw += res.t_raw;
111 time_512 += res.t_512;
113 printf("Zero test:\n");
114 printf("Raw xbzrle_encode time is %f ms\n", time_raw);
115 printf("512 xbzrle_encode time is %f ms\n", time_512);
118 static void encode_decode_unchanged(struct ResTime *res)
120 uint8_t *compressed = g_malloc0(XBZRLE_PAGE_SIZE);
121 uint8_t *test = g_malloc0(XBZRLE_PAGE_SIZE);
122 uint8_t *compressed512 = g_malloc0(XBZRLE_PAGE_SIZE);
123 uint8_t *test512 = g_malloc0(XBZRLE_PAGE_SIZE);
124 int i = 0;
125 int dlen = 0, dlen512 = 0;
126 int diff_len = g_test_rand_int_range(0, XBZRLE_PAGE_SIZE - 1006);
128 for (i = diff_len; i > 0; i--) {
129 test[1000 + i] = i + 4;
130 test512[1000 + i] = i + 4;
133 test[1000 + diff_len + 3] = 107;
134 test[1000 + diff_len + 5] = 109;
136 test512[1000 + diff_len + 3] = 107;
137 test512[1000 + diff_len + 5] = 109;
139 /* test unchanged buffer */
140 time_t t_start, t_end, t_start512, t_end512;
141 t_start = clock();
142 dlen = xbzrle_encode_buffer(test, test, XBZRLE_PAGE_SIZE, compressed,
143 XBZRLE_PAGE_SIZE);
144 t_end = clock();
145 float time_val = difftime(t_end, t_start);
146 g_assert(dlen == 0);
148 t_start512 = clock();
149 dlen512 = xbzrle_encode_buffer_avx512(test512, test512, XBZRLE_PAGE_SIZE,
150 compressed512, XBZRLE_PAGE_SIZE);
151 t_end512 = clock();
152 float time_val512 = difftime(t_end512, t_start512);
153 g_assert(dlen512 == 0);
155 res->t_raw = time_val;
156 res->t_512 = time_val512;
158 g_free(test);
159 g_free(compressed);
160 g_free(test512);
161 g_free(compressed512);
165 static void test_encode_decode_unchanged_avx512(void)
167 int i;
168 float time_raw = 0.0, time_512 = 0.0;
169 struct ResTime res;
170 for (i = 0; i < 10000; i++) {
171 encode_decode_unchanged(&res);
172 time_raw += res.t_raw;
173 time_512 += res.t_512;
175 printf("Unchanged test:\n");
176 printf("Raw xbzrle_encode time is %f ms\n", time_raw);
177 printf("512 xbzrle_encode time is %f ms\n", time_512);
180 static void encode_decode_1_byte(struct ResTime *res)
182 uint8_t *buffer = g_malloc0(XBZRLE_PAGE_SIZE);
183 uint8_t *test = g_malloc0(XBZRLE_PAGE_SIZE);
184 uint8_t *compressed = g_malloc(XBZRLE_PAGE_SIZE);
185 uint8_t *buffer512 = g_malloc0(XBZRLE_PAGE_SIZE);
186 uint8_t *test512 = g_malloc0(XBZRLE_PAGE_SIZE);
187 uint8_t *compressed512 = g_malloc(XBZRLE_PAGE_SIZE);
188 int dlen = 0, rc = 0, dlen512 = 0, rc512 = 0;
189 uint8_t buf[2];
190 uint8_t buf512[2];
192 test[XBZRLE_PAGE_SIZE - 1] = 1;
193 test512[XBZRLE_PAGE_SIZE - 1] = 1;
195 time_t t_start, t_end, t_start512, t_end512;
196 t_start = clock();
197 dlen = xbzrle_encode_buffer(buffer, test, XBZRLE_PAGE_SIZE, compressed,
198 XBZRLE_PAGE_SIZE);
199 t_end = clock();
200 float time_val = difftime(t_end, t_start);
201 g_assert(dlen == (uleb128_encode_small(&buf[0], 4095) + 2));
203 rc = xbzrle_decode_buffer(compressed, dlen, buffer, XBZRLE_PAGE_SIZE);
204 g_assert(rc == XBZRLE_PAGE_SIZE);
205 g_assert(memcmp(test, buffer, XBZRLE_PAGE_SIZE) == 0);
207 t_start512 = clock();
208 dlen512 = xbzrle_encode_buffer_avx512(buffer512, test512, XBZRLE_PAGE_SIZE,
209 compressed512, XBZRLE_PAGE_SIZE);
210 t_end512 = clock();
211 float time_val512 = difftime(t_end512, t_start512);
212 g_assert(dlen512 == (uleb128_encode_small(&buf512[0], 4095) + 2));
214 rc512 = xbzrle_decode_buffer(compressed512, dlen512, buffer512,
215 XBZRLE_PAGE_SIZE);
216 g_assert(rc512 == XBZRLE_PAGE_SIZE);
217 g_assert(memcmp(test512, buffer512, XBZRLE_PAGE_SIZE) == 0);
219 res->t_raw = time_val;
220 res->t_512 = time_val512;
222 g_free(buffer);
223 g_free(compressed);
224 g_free(test);
225 g_free(buffer512);
226 g_free(compressed512);
227 g_free(test512);
231 static void test_encode_decode_1_byte_avx512(void)
233 int i;
234 float time_raw = 0.0, time_512 = 0.0;
235 struct ResTime res;
236 for (i = 0; i < 10000; i++) {
237 encode_decode_1_byte(&res);
238 time_raw += res.t_raw;
239 time_512 += res.t_512;
241 printf("1 byte test:\n");
242 printf("Raw xbzrle_encode time is %f ms\n", time_raw);
243 printf("512 xbzrle_encode time is %f ms\n", time_512);
246 static void encode_decode_overflow(struct ResTime *res)
248 uint8_t *compressed = g_malloc0(XBZRLE_PAGE_SIZE);
249 uint8_t *test = g_malloc0(XBZRLE_PAGE_SIZE);
250 uint8_t *buffer = g_malloc0(XBZRLE_PAGE_SIZE);
251 uint8_t *compressed512 = g_malloc0(XBZRLE_PAGE_SIZE);
252 uint8_t *test512 = g_malloc0(XBZRLE_PAGE_SIZE);
253 uint8_t *buffer512 = g_malloc0(XBZRLE_PAGE_SIZE);
254 int i = 0, rc = 0, rc512 = 0;
256 for (i = 0; i < XBZRLE_PAGE_SIZE / 2 - 1; i++) {
257 test[i * 2] = 1;
258 test512[i * 2] = 1;
261 /* encode overflow */
262 time_t t_start, t_end, t_start512, t_end512;
263 t_start = clock();
264 rc = xbzrle_encode_buffer(buffer, test, XBZRLE_PAGE_SIZE, compressed,
265 XBZRLE_PAGE_SIZE);
266 t_end = clock();
267 float time_val = difftime(t_end, t_start);
268 g_assert(rc == -1);
270 t_start512 = clock();
271 rc512 = xbzrle_encode_buffer_avx512(buffer512, test512, XBZRLE_PAGE_SIZE,
272 compressed512, XBZRLE_PAGE_SIZE);
273 t_end512 = clock();
274 float time_val512 = difftime(t_end512, t_start512);
275 g_assert(rc512 == -1);
277 res->t_raw = time_val;
278 res->t_512 = time_val512;
280 g_free(buffer);
281 g_free(compressed);
282 g_free(test);
283 g_free(buffer512);
284 g_free(compressed512);
285 g_free(test512);
289 static void test_encode_decode_overflow_avx512(void)
291 int i;
292 float time_raw = 0.0, time_512 = 0.0;
293 struct ResTime res;
294 for (i = 0; i < 10000; i++) {
295 encode_decode_overflow(&res);
296 time_raw += res.t_raw;
297 time_512 += res.t_512;
299 printf("Overflow test:\n");
300 printf("Raw xbzrle_encode time is %f ms\n", time_raw);
301 printf("512 xbzrle_encode time is %f ms\n", time_512);
304 static void encode_decode_range_avx512(struct ResTime *res)
306 uint8_t *buffer = g_malloc0(XBZRLE_PAGE_SIZE);
307 uint8_t *compressed = g_malloc(XBZRLE_PAGE_SIZE);
308 uint8_t *test = g_malloc0(XBZRLE_PAGE_SIZE);
309 uint8_t *buffer512 = g_malloc0(XBZRLE_PAGE_SIZE);
310 uint8_t *compressed512 = g_malloc(XBZRLE_PAGE_SIZE);
311 uint8_t *test512 = g_malloc0(XBZRLE_PAGE_SIZE);
312 int i = 0, rc = 0, rc512 = 0;
313 int dlen = 0, dlen512 = 0;
315 int diff_len = g_test_rand_int_range(0, XBZRLE_PAGE_SIZE - 1006);
317 for (i = diff_len; i > 0; i--) {
318 buffer[1000 + i] = i;
319 test[1000 + i] = i + 4;
320 buffer512[1000 + i] = i;
321 test512[1000 + i] = i + 4;
324 buffer[1000 + diff_len + 3] = 103;
325 test[1000 + diff_len + 3] = 107;
327 buffer[1000 + diff_len + 5] = 105;
328 test[1000 + diff_len + 5] = 109;
330 buffer512[1000 + diff_len + 3] = 103;
331 test512[1000 + diff_len + 3] = 107;
333 buffer512[1000 + diff_len + 5] = 105;
334 test512[1000 + diff_len + 5] = 109;
336 /* test encode/decode */
337 time_t t_start, t_end, t_start512, t_end512;
338 t_start = clock();
339 dlen = xbzrle_encode_buffer(test, buffer, XBZRLE_PAGE_SIZE, compressed,
340 XBZRLE_PAGE_SIZE);
341 t_end = clock();
342 float time_val = difftime(t_end, t_start);
343 rc = xbzrle_decode_buffer(compressed, dlen, test, XBZRLE_PAGE_SIZE);
344 g_assert(rc < XBZRLE_PAGE_SIZE);
345 g_assert(memcmp(test, buffer, XBZRLE_PAGE_SIZE) == 0);
347 t_start512 = clock();
348 dlen512 = xbzrle_encode_buffer_avx512(test512, buffer512, XBZRLE_PAGE_SIZE,
349 compressed512, XBZRLE_PAGE_SIZE);
350 t_end512 = clock();
351 float time_val512 = difftime(t_end512, t_start512);
352 rc512 = xbzrle_decode_buffer(compressed512, dlen512, test512, XBZRLE_PAGE_SIZE);
353 g_assert(rc512 < XBZRLE_PAGE_SIZE);
354 g_assert(memcmp(test512, buffer512, XBZRLE_PAGE_SIZE) == 0);
356 res->t_raw = time_val;
357 res->t_512 = time_val512;
359 g_free(buffer);
360 g_free(compressed);
361 g_free(test);
362 g_free(buffer512);
363 g_free(compressed512);
364 g_free(test512);
368 static void test_encode_decode_avx512(void)
370 int i;
371 float time_raw = 0.0, time_512 = 0.0;
372 struct ResTime res;
373 for (i = 0; i < 10000; i++) {
374 encode_decode_range_avx512(&res);
375 time_raw += res.t_raw;
376 time_512 += res.t_512;
378 printf("Encode decode test:\n");
379 printf("Raw xbzrle_encode time is %f ms\n", time_raw);
380 printf("512 xbzrle_encode time is %f ms\n", time_512);
383 static void encode_decode_random(struct ResTime *res)
385 uint8_t *buffer = g_malloc0(XBZRLE_PAGE_SIZE);
386 uint8_t *compressed = g_malloc(XBZRLE_PAGE_SIZE);
387 uint8_t *test = g_malloc0(XBZRLE_PAGE_SIZE);
388 uint8_t *buffer512 = g_malloc0(XBZRLE_PAGE_SIZE);
389 uint8_t *compressed512 = g_malloc(XBZRLE_PAGE_SIZE);
390 uint8_t *test512 = g_malloc0(XBZRLE_PAGE_SIZE);
391 int i = 0, rc = 0, rc512 = 0;
392 int dlen = 0, dlen512 = 0;
394 int diff_len = g_test_rand_int_range(0, XBZRLE_PAGE_SIZE - 1);
395 /* store the index of diff */
396 int dirty_index[diff_len];
397 for (int j = 0; j < diff_len; j++) {
398 dirty_index[j] = g_test_rand_int_range(0, XBZRLE_PAGE_SIZE - 1);
400 for (i = diff_len - 1; i >= 0; i--) {
401 buffer[dirty_index[i]] = i;
402 test[dirty_index[i]] = i + 4;
403 buffer512[dirty_index[i]] = i;
404 test512[dirty_index[i]] = i + 4;
407 time_t t_start, t_end, t_start512, t_end512;
408 t_start = clock();
409 dlen = xbzrle_encode_buffer(test, buffer, XBZRLE_PAGE_SIZE, compressed,
410 XBZRLE_PAGE_SIZE);
411 t_end = clock();
412 float time_val = difftime(t_end, t_start);
413 rc = xbzrle_decode_buffer(compressed, dlen, test, XBZRLE_PAGE_SIZE);
414 g_assert(rc < XBZRLE_PAGE_SIZE);
416 t_start512 = clock();
417 dlen512 = xbzrle_encode_buffer_avx512(test512, buffer512, XBZRLE_PAGE_SIZE,
418 compressed512, XBZRLE_PAGE_SIZE);
419 t_end512 = clock();
420 float time_val512 = difftime(t_end512, t_start512);
421 rc512 = xbzrle_decode_buffer(compressed512, dlen512, test512, XBZRLE_PAGE_SIZE);
422 g_assert(rc512 < XBZRLE_PAGE_SIZE);
424 res->t_raw = time_val;
425 res->t_512 = time_val512;
427 g_free(buffer);
428 g_free(compressed);
429 g_free(test);
430 g_free(buffer512);
431 g_free(compressed512);
432 g_free(test512);
436 static void test_encode_decode_random_avx512(void)
438 int i;
439 float time_raw = 0.0, time_512 = 0.0;
440 struct ResTime res;
441 for (i = 0; i < 10000; i++) {
442 encode_decode_random(&res);
443 time_raw += res.t_raw;
444 time_512 += res.t_512;
446 printf("Random test:\n");
447 printf("Raw xbzrle_encode time is %f ms\n", time_raw);
448 printf("512 xbzrle_encode time is %f ms\n", time_512);
450 #endif
452 int main(int argc, char **argv)
454 g_test_init(&argc, &argv, NULL);
455 g_test_rand_int();
456 #if defined(CONFIG_AVX512BW_OPT)
457 if (likely(is_cpu_support_avx512bw)) {
458 g_test_add_func("/xbzrle/encode_decode_zero", test_encode_decode_zero_avx512);
459 g_test_add_func("/xbzrle/encode_decode_unchanged",
460 test_encode_decode_unchanged_avx512);
461 g_test_add_func("/xbzrle/encode_decode_1_byte", test_encode_decode_1_byte_avx512);
462 g_test_add_func("/xbzrle/encode_decode_overflow",
463 test_encode_decode_overflow_avx512);
464 g_test_add_func("/xbzrle/encode_decode", test_encode_decode_avx512);
465 g_test_add_func("/xbzrle/encode_decode_random", test_encode_decode_random_avx512);
467 #endif
468 return g_test_run();