VirtualBox

source: vbox/trunk/src/VBox/VMM/testcase/tstCompressionBenchmark.cpp@ 60307

Last change on this file since 60307 was 59747, checked in by vboxsync, 9 years ago

iprt/asm.h: Cleaned up the ASMMemIsAll8/U32 mess and implmeneted the former in assembly. (Found inverted usage due to bad naming in copyUtf8Block, but it is fortunately an unused method.) Replaces the complicated ASMBitFirstSet based scanning in RTSgBufIsZero with a simple call to the new ASMMemIsZero function.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 25.3 KB
Line 
1/* $Id: tstCompressionBenchmark.cpp 59747 2016-02-19 23:18:18Z vboxsync $ */
2/** @file
3 * Compression Benchmark for SSM and PGM.
4 */
5
6/*
7 * Copyright (C) 2009-2015 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18
19/*********************************************************************************************************************************
20* Header Files *
21*********************************************************************************************************************************/
22#include <iprt/asm.h>
23#include <iprt/assert.h>
24#include <iprt/buildconfig.h>
25#include <iprt/crc.h>
26#include <iprt/ctype.h>
27#include <iprt/err.h>
28#include <iprt/file.h>
29#include <iprt/getopt.h>
30#include <iprt/initterm.h>
31#include <iprt/md5.h>
32#include <iprt/sha.h>
33#include <iprt/mem.h>
34#include <iprt/param.h>
35#include <iprt/stream.h>
36#include <iprt/string.h>
37#include <iprt/time.h>
38#include <iprt/zip.h>
39
40
41/*********************************************************************************************************************************
42* Global Variables *
43*********************************************************************************************************************************/
44static size_t g_cPages = 20*_1M / PAGE_SIZE;
45static size_t g_cbPages;
46static uint8_t *g_pabSrc;
47
48/** Buffer for the decompressed data (g_cbPages). */
49static uint8_t *g_pabDecompr;
50
51/** Buffer for the compressed data (g_cbComprAlloc). */
52static uint8_t *g_pabCompr;
53/** The current size of the compressed data, ComprOutCallback */
54static size_t g_cbCompr;
55/** The current offset into the compressed data, DecomprInCallback. */
56static size_t g_offComprIn;
57/** The amount of space allocated for compressed data. */
58static size_t g_cbComprAlloc;
59
60
61/**
62 * Store compressed data in the g_pabCompr buffer.
63 */
64static DECLCALLBACK(int) ComprOutCallback(void *pvUser, const void *pvBuf, size_t cbBuf)
65{
66 NOREF(pvUser);
67 AssertReturn(g_cbCompr + cbBuf <= g_cbComprAlloc, VERR_BUFFER_OVERFLOW);
68 memcpy(&g_pabCompr[g_cbCompr], pvBuf, cbBuf);
69 g_cbCompr += cbBuf;
70 return VINF_SUCCESS;
71}
72
73/**
74 * Read compressed data from g_pabComrp.
75 */
76static DECLCALLBACK(int) DecomprInCallback(void *pvUser, void *pvBuf, size_t cbBuf, size_t *pcbBuf)
77{
78 NOREF(pvUser);
79 size_t cb = RT_MIN(cbBuf, g_cbCompr - g_offComprIn);
80 if (pcbBuf)
81 *pcbBuf = cb;
82// AssertReturn(cb > 0, VERR_EOF);
83 memcpy(pvBuf, &g_pabCompr[g_offComprIn], cb);
84 g_offComprIn += cb;
85 return VINF_SUCCESS;
86}
87
88
89/**
90 * Benchmark RTCrc routines potentially relevant for SSM or PGM - All in one go.
91 *
92 * @param pabSrc Pointer to the test data.
93 * @param cbSrc The size of the test data.
94 */
95static void tstBenchmarkCRCsAllInOne(uint8_t const *pabSrc, size_t cbSrc)
96{
97 RTPrintf("Algorithm Speed Time Digest\n"
98 "------------------------------------------------------------------------------\n");
99
100 uint64_t NanoTS = RTTimeNanoTS();
101 uint32_t u32Crc = RTCrc32(pabSrc, cbSrc);
102 NanoTS = RTTimeNanoTS() - NanoTS;
103 unsigned uSpeed = (unsigned)(cbSrc / (long double)NanoTS * 1000000000.0 / 1024);
104 RTPrintf("CRC-32 %'9u KB/s %'15llu ns - %08x\n", uSpeed, NanoTS, u32Crc);
105
106
107 NanoTS = RTTimeNanoTS();
108 uint64_t u64Crc = RTCrc64(pabSrc, cbSrc);
109 NanoTS = RTTimeNanoTS() - NanoTS;
110 uSpeed = (unsigned)(cbSrc / (long double)NanoTS * 1000000000.0 / 1024);
111 RTPrintf("CRC-64 %'9u KB/s %'15llu ns - %016llx\n", uSpeed, NanoTS, u64Crc);
112
113 NanoTS = RTTimeNanoTS();
114 u32Crc = RTCrcAdler32(pabSrc, cbSrc);
115 NanoTS = RTTimeNanoTS() - NanoTS;
116 uSpeed = (unsigned)(cbSrc / (long double)NanoTS * 1000000000.0 / 1024);
117 RTPrintf("Adler-32 %'9u KB/s %'15llu ns - %08x\n", uSpeed, NanoTS, u32Crc);
118
119 NanoTS = RTTimeNanoTS();
120 uint8_t abMd5Hash[RTMD5HASHSIZE];
121 RTMd5(pabSrc, cbSrc, abMd5Hash);
122 NanoTS = RTTimeNanoTS() - NanoTS;
123 uSpeed = (unsigned)(cbSrc / (long double)NanoTS * 1000000000.0 / 1024);
124 char szDigest[257];
125 RTMd5ToString(abMd5Hash, szDigest, sizeof(szDigest));
126 RTPrintf("MD5 %'9u KB/s %'15llu ns - %s\n", uSpeed, NanoTS, szDigest);
127
128 NanoTS = RTTimeNanoTS();
129 uint8_t abSha1Hash[RTSHA1_HASH_SIZE];
130 RTSha1(pabSrc, cbSrc, abSha1Hash);
131 NanoTS = RTTimeNanoTS() - NanoTS;
132 uSpeed = (unsigned)(cbSrc / (long double)NanoTS * 1000000000.0 / 1024);
133 RTSha1ToString(abSha1Hash, szDigest, sizeof(szDigest));
134 RTPrintf("SHA-1 %'9u KB/s %'15llu ns - %s\n", uSpeed, NanoTS, szDigest);
135
136 NanoTS = RTTimeNanoTS();
137 uint8_t abSha256Hash[RTSHA256_HASH_SIZE];
138 RTSha256(pabSrc, cbSrc, abSha256Hash);
139 NanoTS = RTTimeNanoTS() - NanoTS;
140 uSpeed = (unsigned)(cbSrc / (long double)NanoTS * 1000000000.0 / 1024);
141 RTSha256ToString(abSha256Hash, szDigest, sizeof(szDigest));
142 RTPrintf("SHA-256 %'9u KB/s %'15llu ns - %s\n", uSpeed, NanoTS, szDigest);
143
144 NanoTS = RTTimeNanoTS();
145 uint8_t abSha512Hash[RTSHA512_HASH_SIZE];
146 RTSha512(pabSrc, cbSrc, abSha512Hash);
147 NanoTS = RTTimeNanoTS() - NanoTS;
148 uSpeed = (unsigned)(cbSrc / (long double)NanoTS * 1000000000.0 / 1024);
149 RTSha512ToString(abSha512Hash, szDigest, sizeof(szDigest));
150 RTPrintf("SHA-512 %'9u KB/s %'15llu ns - %s\n", uSpeed, NanoTS, szDigest);
151}
152
153
154/**
155 * Benchmark RTCrc routines potentially relevant for SSM or PGM - Page by page.
156 *
157 * @param pabSrc Pointer to the test data.
158 * @param cbSrc The size of the test data.
159 */
160static void tstBenchmarkCRCsPageByPage(uint8_t const *pabSrc, size_t cbSrc)
161{
162 RTPrintf("Algorithm Speed Time \n"
163 "----------------------------------------------\n");
164
165 size_t const cPages = cbSrc / PAGE_SIZE;
166
167 uint64_t NanoTS = RTTimeNanoTS();
168 for (uint32_t iPage = 0; iPage < cPages; iPage++)
169 RTCrc32(&pabSrc[iPage * PAGE_SIZE], PAGE_SIZE);
170 NanoTS = RTTimeNanoTS() - NanoTS;
171 unsigned uSpeed = (unsigned)(cbSrc / (long double)NanoTS * 1000000000.0 / 1024);
172 RTPrintf("CRC-32 %'9u KB/s %'15llu ns\n", uSpeed, NanoTS);
173
174
175 NanoTS = RTTimeNanoTS();
176 for (uint32_t iPage = 0; iPage < cPages; iPage++)
177 RTCrc64(&pabSrc[iPage * PAGE_SIZE], PAGE_SIZE);
178 NanoTS = RTTimeNanoTS() - NanoTS;
179 uSpeed = (unsigned)(cbSrc / (long double)NanoTS * 1000000000.0 / 1024);
180 RTPrintf("CRC-64 %'9u KB/s %'15llu ns\n", uSpeed, NanoTS);
181
182 NanoTS = RTTimeNanoTS();
183 for (uint32_t iPage = 0; iPage < cPages; iPage++)
184 RTCrcAdler32(&pabSrc[iPage * PAGE_SIZE], PAGE_SIZE);
185 NanoTS = RTTimeNanoTS() - NanoTS;
186 uSpeed = (unsigned)(cbSrc / (long double)NanoTS * 1000000000.0 / 1024);
187 RTPrintf("Adler-32 %'9u KB/s %'15llu ns\n", uSpeed, NanoTS);
188
189 NanoTS = RTTimeNanoTS();
190 uint8_t abMd5Hash[RTMD5HASHSIZE];
191 for (uint32_t iPage = 0; iPage < cPages; iPage++)
192 RTMd5(&pabSrc[iPage * PAGE_SIZE], PAGE_SIZE, abMd5Hash);
193 NanoTS = RTTimeNanoTS() - NanoTS;
194 uSpeed = (unsigned)(cbSrc / (long double)NanoTS * 1000000000.0 / 1024);
195 RTPrintf("MD5 %'9u KB/s %'15llu ns\n", uSpeed, NanoTS);
196
197 NanoTS = RTTimeNanoTS();
198 uint8_t abSha1Hash[RTSHA1_HASH_SIZE];
199 for (uint32_t iPage = 0; iPage < cPages; iPage++)
200 RTSha1(&pabSrc[iPage * PAGE_SIZE], PAGE_SIZE, abSha1Hash);
201 NanoTS = RTTimeNanoTS() - NanoTS;
202 uSpeed = (unsigned)(cbSrc / (long double)NanoTS * 1000000000.0 / 1024);
203 RTPrintf("SHA-1 %'9u KB/s %'15llu ns\n", uSpeed, NanoTS);
204
205 NanoTS = RTTimeNanoTS();
206 uint8_t abSha256Hash[RTSHA256_HASH_SIZE];
207 for (uint32_t iPage = 0; iPage < cPages; iPage++)
208 RTSha256(&pabSrc[iPage * PAGE_SIZE], PAGE_SIZE, abSha256Hash);
209 NanoTS = RTTimeNanoTS() - NanoTS;
210 uSpeed = (unsigned)(cbSrc / (long double)NanoTS * 1000000000.0 / 1024);
211 RTPrintf("SHA-256 %'9u KB/s %'15llu ns\n", uSpeed, NanoTS);
212
213 NanoTS = RTTimeNanoTS();
214 uint8_t abSha512Hash[RTSHA512_HASH_SIZE];
215 for (uint32_t iPage = 0; iPage < cPages; iPage++)
216 RTSha512(&pabSrc[iPage * PAGE_SIZE], PAGE_SIZE, abSha512Hash);
217 NanoTS = RTTimeNanoTS() - NanoTS;
218 uSpeed = (unsigned)(cbSrc / (long double)NanoTS * 1000000000.0 / 1024);
219 RTPrintf("SHA-512 %'9u KB/s %'15llu ns\n", uSpeed, NanoTS);
220}
221
222
223/** Prints an error message and returns 1 for quick return from main use. */
224static int Error(const char *pszMsgFmt, ...)
225{
226 RTStrmPrintf(g_pStdErr, "\nerror: ");
227 va_list va;
228 va_start(va, pszMsgFmt);
229 RTStrmPrintfV(g_pStdErr, pszMsgFmt, va);
230 va_end(va);
231 return 1;
232}
233
234
235int main(int argc, char **argv)
236{
237 RTR3InitExe(argc, &argv, 0);
238
239 /*
240 * Parse arguments.
241 */
242 static const RTGETOPTDEF s_aOptions[] =
243 {
244 { "--iterations", 'i', RTGETOPT_REQ_UINT32 },
245 { "--num-pages", 'n', RTGETOPT_REQ_UINT32 },
246 { "--page-at-a-time", 'c', RTGETOPT_REQ_UINT32 },
247 { "--page-file", 'f', RTGETOPT_REQ_STRING },
248 { "--offset", 'o', RTGETOPT_REQ_UINT64 },
249 };
250
251 const char *pszPageFile = NULL;
252 uint64_t offPageFile = 0;
253 uint32_t cIterations = 1;
254 uint32_t cPagesAtATime = 1;
255 RTGETOPTUNION Val;
256 RTGETOPTSTATE State;
257 int rc = RTGetOptInit(&State, argc, argv, &s_aOptions[0], RT_ELEMENTS(s_aOptions), 1, 0);
258 AssertRCReturn(rc, 1);
259
260 while ((rc = RTGetOpt(&State, &Val)))
261 {
262 switch (rc)
263 {
264 case 'n':
265 g_cPages = Val.u32;
266 if (g_cPages * PAGE_SIZE * 4 / (PAGE_SIZE * 4) != g_cPages)
267 return Error("The specified page count is too high: %#x (%#llx bytes)\n", g_cPages, (uint64_t)g_cPages * PAGE_SHIFT);
268 if (g_cPages < 1)
269 return Error("The specified page count is too low: %#x\n", g_cPages);
270 break;
271
272 case 'i':
273 cIterations = Val.u32;
274 if (cIterations < 1)
275 return Error("The number of iterations must be 1 or higher\n");
276 break;
277
278 case 'c':
279 cPagesAtATime = Val.u32;
280 if (cPagesAtATime < 1 || cPagesAtATime > 10240)
281 return Error("The specified pages-at-a-time count is out of range: %#x\n", cPagesAtATime);
282 break;
283
284 case 'f':
285 pszPageFile = Val.psz;
286 break;
287
288 case 'o':
289 offPageFile = Val.u64;
290 break;
291
292 case 'O':
293 offPageFile = Val.u64 * PAGE_SIZE;
294 break;
295
296 case 'h':
297 RTPrintf("syntax: tstCompressionBenchmark [options]\n"
298 "\n"
299 "Options:\n"
300 " -h, --help\n"
301 " Show this help page\n"
302 " -i, --iterations <num>\n"
303 " The number of iterations.\n"
304 " -n, --num-pages <pages>\n"
305 " The number of pages.\n"
306 " -c, --pages-at-a-time <pages>\n"
307 " Number of pages at a time.\n"
308 " -f, --page-file <filename>\n"
309 " File or device to read the page from. The default\n"
310 " is to generate some garbage.\n"
311 " -o, --offset <file-offset>\n"
312 " Offset into the page file to start reading at.\n");
313 return 0;
314
315 case 'V':
316 RTPrintf("%sr%s\n", RTBldCfgVersion(), RTBldCfgRevisionStr());
317 return 0;
318
319 default:
320 return RTGetOptPrintError(rc, &Val);
321 }
322 }
323
324 g_cbPages = g_cPages * PAGE_SIZE;
325 uint64_t cbTotal = (uint64_t)g_cPages * PAGE_SIZE * cIterations;
326 uint64_t cbTotalKB = cbTotal / _1K;
327 if (cbTotal / cIterations != g_cbPages)
328 return Error("cPages * cIterations -> overflow\n");
329
330 /*
331 * Gather the test memory.
332 */
333 if (pszPageFile)
334 {
335 size_t cbFile;
336 rc = RTFileReadAllEx(pszPageFile, offPageFile, g_cbPages, RTFILE_RDALL_O_DENY_NONE, (void **)&g_pabSrc, &cbFile);
337 if (RT_FAILURE(rc))
338 return Error("Error reading %zu bytes from %s at %llu: %Rrc\n", g_cbPages, pszPageFile, offPageFile, rc);
339 if (cbFile != g_cbPages)
340 return Error("Error reading %zu bytes from %s at %llu: got %zu bytes\n", g_cbPages, pszPageFile, offPageFile, cbFile);
341 }
342 else
343 {
344 g_pabSrc = (uint8_t *)RTMemAlloc(g_cbPages);
345 if (g_pabSrc)
346 {
347 /* Just fill it with something - warn about the low quality of the something. */
348 RTPrintf("tstCompressionBenchmark: WARNING! No input file was specified so the source\n"
349 "buffer will be filled with generated data of questionable quality.\n");
350#ifdef RT_OS_LINUX
351 RTPrintf("To get real RAM on linux: sudo dd if=/dev/mem ... \n");
352#endif
353 uint8_t *pb = g_pabSrc;
354 uint8_t *pbEnd = &g_pabSrc[g_cbPages];
355 for (; pb != pbEnd; pb += 16)
356 {
357 char szTmp[17];
358 RTStrPrintf(szTmp, sizeof(szTmp), "aaaa%08Xzzzz", (uint32_t)(uintptr_t)pb);
359 memcpy(pb, szTmp, 16);
360 }
361 }
362 }
363
364 g_pabDecompr = (uint8_t *)RTMemAlloc(g_cbPages);
365 g_cbComprAlloc = RT_MAX(g_cbPages * 2, 256 * PAGE_SIZE);
366 g_pabCompr = (uint8_t *)RTMemAlloc(g_cbComprAlloc);
367 if (!g_pabSrc || !g_pabDecompr || !g_pabCompr)
368 return Error("failed to allocate memory buffers (g_cPages=%#x)\n", g_cPages);
369
370 /*
371 * Double loop compressing and uncompressing the data, where the outer does
372 * the specified number of iterations while the inner applies the different
373 * compression algorithms.
374 */
375 struct
376 {
377 /** The time spent decompressing. */
378 uint64_t cNanoDecompr;
379 /** The time spent compressing. */
380 uint64_t cNanoCompr;
381 /** The size of the compressed data. */
382 uint64_t cbCompr;
383 /** First error. */
384 int rc;
385 /** The compression style: block or stream. */
386 bool fBlock;
387 /** Compression type. */
388 RTZIPTYPE enmType;
389 /** Compression level. */
390 RTZIPLEVEL enmLevel;
391 /** Method name. */
392 const char *pszName;
393 } aTests[] =
394 {
395 { 0, 0, 0, VINF_SUCCESS, false, RTZIPTYPE_STORE, RTZIPLEVEL_DEFAULT, "RTZip/Store" },
396 { 0, 0, 0, VINF_SUCCESS, false, RTZIPTYPE_LZF, RTZIPLEVEL_DEFAULT, "RTZip/LZF" },
397/* { 0, 0, 0, VINF_SUCCESS, false, RTZIPTYPE_ZLIB, RTZIPLEVEL_DEFAULT, "RTZip/zlib" }, - slow plus it randomly hits VERR_GENERAL_FAILURE atm. */
398 { 0, 0, 0, VINF_SUCCESS, true, RTZIPTYPE_STORE, RTZIPLEVEL_DEFAULT, "RTZipBlock/Store" },
399 { 0, 0, 0, VINF_SUCCESS, true, RTZIPTYPE_LZF, RTZIPLEVEL_DEFAULT, "RTZipBlock/LZF" },
400 { 0, 0, 0, VINF_SUCCESS, true, RTZIPTYPE_LZJB, RTZIPLEVEL_DEFAULT, "RTZipBlock/LZJB" },
401 { 0, 0, 0, VINF_SUCCESS, true, RTZIPTYPE_LZO, RTZIPLEVEL_DEFAULT, "RTZipBlock/LZO" },
402 };
403 RTPrintf("tstCompressionBenchmark: TESTING..");
404 for (uint32_t i = 0; i < cIterations; i++)
405 {
406 for (uint32_t j = 0; j < RT_ELEMENTS(aTests); j++)
407 {
408 if (RT_FAILURE(aTests[j].rc))
409 continue;
410 memset(g_pabCompr, 0xaa, g_cbComprAlloc);
411 memset(g_pabDecompr, 0xcc, g_cbPages);
412 g_cbCompr = 0;
413 g_offComprIn = 0;
414 RTPrintf("."); RTStrmFlush(g_pStdOut);
415
416 /*
417 * Compress it.
418 */
419 uint64_t NanoTS = RTTimeNanoTS();
420 if (aTests[j].fBlock)
421 {
422 size_t cbLeft = g_cbComprAlloc;
423 uint8_t const *pbSrcPage = g_pabSrc;
424 uint8_t *pbDstPage = g_pabCompr;
425 for (size_t iPage = 0; iPage < g_cPages; iPage += cPagesAtATime)
426 {
427 AssertBreakStmt(cbLeft > PAGE_SIZE * 4, aTests[j].rc = rc = VERR_BUFFER_OVERFLOW);
428 uint32_t *pcb = (uint32_t *)pbDstPage;
429 pbDstPage += sizeof(uint32_t);
430 cbLeft -= sizeof(uint32_t);
431 size_t cbSrc = RT_MIN(g_cPages - iPage, cPagesAtATime) * PAGE_SIZE;
432 size_t cbDst;
433 rc = RTZipBlockCompress(aTests[j].enmType, aTests[j].enmLevel, 0 /*fFlags*/,
434 pbSrcPage, cbSrc,
435 pbDstPage, cbLeft, &cbDst);
436 if (RT_FAILURE(rc))
437 {
438 Error("RTZipBlockCompress failed for '%s' (#%u): %Rrc\n", aTests[j].pszName, j, rc);
439 aTests[j].rc = rc;
440 break;
441 }
442 *pcb = (uint32_t)cbDst;
443 cbLeft -= cbDst;
444 pbDstPage += cbDst;
445 pbSrcPage += cbSrc;
446 }
447 if (RT_FAILURE(rc))
448 continue;
449 g_cbCompr = pbDstPage - g_pabCompr;
450 }
451 else
452 {
453 PRTZIPCOMP pZipComp;
454 rc = RTZipCompCreate(&pZipComp, NULL, ComprOutCallback, aTests[j].enmType, aTests[j].enmLevel);
455 if (RT_FAILURE(rc))
456 {
457 Error("Failed to create the compressor for '%s' (#%u): %Rrc\n", aTests[j].pszName, j, rc);
458 aTests[j].rc = rc;
459 continue;
460 }
461
462 uint8_t const *pbSrcPage = g_pabSrc;
463 for (size_t iPage = 0; iPage < g_cPages; iPage += cPagesAtATime)
464 {
465 size_t cb = RT_MIN(g_cPages - iPage, cPagesAtATime) * PAGE_SIZE;
466 rc = RTZipCompress(pZipComp, pbSrcPage, cb);
467 if (RT_FAILURE(rc))
468 {
469 Error("RTZipCompress failed for '%s' (#%u): %Rrc\n", aTests[j].pszName, j, rc);
470 aTests[j].rc = rc;
471 break;
472 }
473 pbSrcPage += cb;
474 }
475 if (RT_FAILURE(rc))
476 continue;
477 rc = RTZipCompFinish(pZipComp);
478 if (RT_FAILURE(rc))
479 {
480 Error("RTZipCompFinish failed for '%s' (#%u): %Rrc\n", aTests[j].pszName, j, rc);
481 aTests[j].rc = rc;
482 break;
483 }
484 RTZipCompDestroy(pZipComp);
485 }
486 NanoTS = RTTimeNanoTS() - NanoTS;
487 aTests[j].cbCompr += g_cbCompr;
488 aTests[j].cNanoCompr += NanoTS;
489
490 /*
491 * Decompress it.
492 */
493 NanoTS = RTTimeNanoTS();
494 if (aTests[j].fBlock)
495 {
496 uint8_t const *pbSrcPage = g_pabCompr;
497 size_t cbLeft = g_cbCompr;
498 uint8_t *pbDstPage = g_pabDecompr;
499 for (size_t iPage = 0; iPage < g_cPages; iPage += cPagesAtATime)
500 {
501 size_t cbDst = RT_MIN(g_cPages - iPage, cPagesAtATime) * PAGE_SIZE;
502 size_t cbSrc = *(uint32_t *)pbSrcPage;
503 pbSrcPage += sizeof(uint32_t);
504 cbLeft -= sizeof(uint32_t);
505 rc = RTZipBlockDecompress(aTests[j].enmType, 0 /*fFlags*/,
506 pbSrcPage, cbSrc, &cbSrc,
507 pbDstPage, cbDst, &cbDst);
508 if (RT_FAILURE(rc))
509 {
510 Error("RTZipBlockDecompress failed for '%s' (#%u): %Rrc\n", aTests[j].pszName, j, rc);
511 aTests[j].rc = rc;
512 break;
513 }
514 pbDstPage += cbDst;
515 cbLeft -= cbSrc;
516 pbSrcPage += cbSrc;
517 }
518 if (RT_FAILURE(rc))
519 continue;
520 }
521 else
522 {
523 PRTZIPDECOMP pZipDecomp;
524 rc = RTZipDecompCreate(&pZipDecomp, NULL, DecomprInCallback);
525 if (RT_FAILURE(rc))
526 {
527 Error("Failed to create the decompressor for '%s' (#%u): %Rrc\n", aTests[j].pszName, j, rc);
528 aTests[j].rc = rc;
529 continue;
530 }
531
532 uint8_t *pbDstPage = g_pabDecompr;
533 for (size_t iPage = 0; iPage < g_cPages; iPage += cPagesAtATime)
534 {
535 size_t cb = RT_MIN(g_cPages - iPage, cPagesAtATime) * PAGE_SIZE;
536 rc = RTZipDecompress(pZipDecomp, pbDstPage, cb, NULL);
537 if (RT_FAILURE(rc))
538 {
539 Error("RTZipDecompress failed for '%s' (#%u): %Rrc\n", aTests[j].pszName, j, rc);
540 aTests[j].rc = rc;
541 break;
542 }
543 pbDstPage += cb;
544 }
545 RTZipDecompDestroy(pZipDecomp);
546 if (RT_FAILURE(rc))
547 continue;
548 }
549 NanoTS = RTTimeNanoTS() - NanoTS;
550 aTests[j].cNanoDecompr += NanoTS;
551
552 if (memcmp(g_pabDecompr, g_pabSrc, g_cbPages))
553 {
554 Error("The compressed data doesn't match the source for '%s' (%#u)\n", aTests[j].pszName, j);
555 aTests[j].rc = VERR_BAD_EXE_FORMAT;
556 continue;
557 }
558 }
559 }
560 if (RT_SUCCESS(rc))
561 RTPrintf("\n");
562
563 /*
564 * Report the results.
565 */
566 rc = 0;
567 RTPrintf("tstCompressionBenchmark: BEGIN RESULTS\n");
568 RTPrintf("%-20s Compression Decompression\n", "");
569 RTPrintf("%-20s In Out Ratio Size In Out\n", "Method");
570 RTPrintf("%.20s-----------------------------------------------------------------------------------------\n", "---------------------------------------------");
571 for (uint32_t j = 0; j < RT_ELEMENTS(aTests); j++)
572 {
573 if (RT_SUCCESS(aTests[j].rc))
574 {
575 unsigned uComprSpeedIn = (unsigned)(cbTotalKB / (long double)aTests[j].cNanoCompr * 1000000000.0);
576 unsigned uComprSpeedOut = (unsigned)(aTests[j].cbCompr / (long double)aTests[j].cNanoCompr * 1000000000.0 / 1024);
577 unsigned uRatio = (unsigned)(aTests[j].cbCompr / cIterations * 100 / g_cbPages);
578 unsigned uDecomprSpeedIn = (unsigned)(aTests[j].cbCompr / (long double)aTests[j].cNanoDecompr * 1000000000.0 / 1024);
579 unsigned uDecomprSpeedOut = (unsigned)(cbTotalKB / (long double)aTests[j].cNanoDecompr * 1000000000.0);
580 RTPrintf("%-20s %'9u KB/s %'9u KB/s %3u%% %'11llu bytes %'9u KB/s %'9u KB/s",
581 aTests[j].pszName,
582 uComprSpeedIn, uComprSpeedOut, uRatio, aTests[j].cbCompr / cIterations,
583 uDecomprSpeedIn, uDecomprSpeedOut);
584#if 0
585 RTPrintf(" [%'14llu / %'14llu ns]\n",
586 aTests[j].cNanoCompr / cIterations,
587 aTests[j].cNanoDecompr / cIterations);
588#else
589 RTPrintf("\n");
590#endif
591 }
592 else
593 {
594 RTPrintf("%-20s: %Rrc\n", aTests[j].pszName, aTests[j].rc);
595 rc = 1;
596 }
597 }
598 if (pszPageFile)
599 RTPrintf("Input: %'10zu pages from '%s' starting at offset %'lld (%#llx)\n"
600 " %'11zu bytes\n",
601 g_cPages, pszPageFile, offPageFile, offPageFile, g_cbPages);
602 else
603 RTPrintf("Input: %'10zu pages of generated rubbish %'11zu bytes\n",
604 g_cPages, g_cbPages);
605
606 /*
607 * Count zero pages in the data set.
608 */
609 size_t cZeroPages = 0;
610 for (size_t iPage = 0; iPage < g_cPages; iPage++)
611 {
612 if (ASMMemIsZeroPage(&g_pabSrc[iPage * PAGE_SIZE]))
613 cZeroPages++;
614 }
615 RTPrintf(" %'10zu zero pages (%u %%)\n", cZeroPages, cZeroPages * 100 / g_cPages);
616
617 /*
618 * A little extension to the test, benchmark relevant CRCs.
619 */
620 RTPrintf("\n"
621 "tstCompressionBenchmark: Hash/CRC - All In One\n");
622 tstBenchmarkCRCsAllInOne(g_pabSrc, g_cbPages);
623
624 RTPrintf("\n"
625 "tstCompressionBenchmark: Hash/CRC - Page by Page\n");
626 tstBenchmarkCRCsPageByPage(g_pabSrc, g_cbPages);
627
628 RTPrintf("\n"
629 "tstCompressionBenchmark: Hash/CRC - Zero Page Digest\n");
630 static uint8_t s_abZeroPg[PAGE_SIZE];
631 RT_ZERO(s_abZeroPg);
632 tstBenchmarkCRCsAllInOne(s_abZeroPg, PAGE_SIZE);
633
634 RTPrintf("\n"
635 "tstCompressionBenchmark: Hash/CRC - Zero Half Page Digest\n");
636 tstBenchmarkCRCsAllInOne(s_abZeroPg, PAGE_SIZE / 2);
637
638 RTPrintf("tstCompressionBenchmark: END RESULTS\n");
639
640 return rc;
641}
642
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette