[Mesa-dev] [PATCH 3/3] util: use zlib's CRC32 implementaion for larger buffers
Grazvydas Ignotas
notasas at gmail.com
Fri Dec 29 01:56:38 UTC 2017
zlib provides a faster slice-by-4 CRC32 implementation than the
traditional single byte lookup one used by mesa. As most supported
platforms now link zlib unconditionally, we can easily use it.
For small buffers the old implementation is still used as it's faster
with cold cache (first call), as indicated by some throughput
benchmarking (avg MB/s, n=100, zlib 1.2.8):
i5-6600K C2D E4500
size mesa zlib mesa zlib
4 66 43 -35% +/- 4.8% 43 22 -49% +/- 9.6%
32 193 171 -11% +/- 5.8% 129 49 -61% +/- 7.2%
64 256 267 4% +/- 4.1% 171 63 -63% +/- 5.4%
128 317 389 22% +/- 5.8% 253 89 -64% +/- 4.2%
256 364 596 63% +/- 5.6% 304 166 -45% +/- 2.8%
512 401 838 108% +/- 5.3% 338 296 -12% +/- 3.1%
1024 420 1036 146% +/- 7.6% 375 461 23% +/- 3.7%
1M 443 1443 225% +/- 2.1% 403 1175 191% +/- 0.9%
100M 448 1452 224% +/- 0.3% 406 1214 198% +/- 0.3%
With hot cache (repeated calls) zlib almost always wins on both CPUS.
It has been verified the calculation results stay the same after this
change.
Signed-off-by: Grazvydas Ignotas <notasas at gmail.com>
---
src/util/crc32.c | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/src/util/crc32.c b/src/util/crc32.c
index f2e01c6..0cffa49 100644
--- a/src/util/crc32.c
+++ b/src/util/crc32.c
@@ -31,12 +31,20 @@
*
* @author Jose Fonseca
*/
+#ifdef HAVE_ZLIB
+#include <zlib.h>
+#endif
#include "crc32.h"
+/* For small buffers it's faster to avoid the library call.
+ * The optimal threshold depends on CPU characteristics, it is hoped
+ * the choice below is reasonable for typical modern CPU.
+ */
+#define ZLIB_SIZE_THRESHOLD 64
static const uint32_t
util_crc32_table[256] = {
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba,
0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
@@ -112,10 +120,15 @@ uint32_t
util_hash_crc32(const void *data, size_t size)
{
const uint8_t *p = data;
uint32_t crc = 0xffffffff;
+#ifdef HAVE_ZLIB
+ if (size >= ZLIB_SIZE_THRESHOLD && (uInt)size == size)
+ return ~crc32(0, data, size);
+#endif
+
while (size--)
crc = util_crc32_table[(crc ^ *p++) & 0xff] ^ (crc >> 8);
return crc;
}
--
2.7.4
More information about the mesa-dev
mailing list