From 4b9118cdb316093e1733264d229c6b7279179e1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristoffer=20Br=C3=A5nemyr?= Date: Wed, 3 Feb 2021 10:35:22 +0100 Subject: cksum: use pclmul hardware instruction for CRC32 calculation Use cpuid to detect CPU support for hardware instruction. Fall back to slice by 8 algorithm if not supported. A 500MiB file improves from 1.40s to 0.67s on an i3-2310M * configure.ac [USE_PCLMUL_CRC32]: A new conditional, set when __get_cpuid() and clmul compiler intrinsics are supported. * src/cksum.c (pclmul_supported): A new function using __get_cpuid() to determine if pclmul instructions are supported. (cksum): A new function refactored from cksum_slice8(), which calls pclmul_supported() and then cksum_slice8() or cksum_pclmul() as appropriate. * src/cksum.h: Export the crctab array for use in the new module. * src/cksum_pclmul.c: A new module to implement using pclmul intrinsics. * po/POTFILES.in: Reference the new cksum_pclmul module. * src/local.mk: Likewise. Note we build it as a separate library so that it can be portably built with separate -mavx etc. flags. * tests/misc/cksum.sh: Add new test modes for pertinent buffer sizes. --- configure.ac | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) (limited to 'configure.ac') diff --git a/configure.ac b/configure.ac index 6351dd708..7fbecbf8d 100644 --- a/configure.ac +++ b/configure.ac @@ -524,6 +524,57 @@ CFLAGS=$ac_save_CFLAGS LDFLAGS=$ac_save_LDFLAGS ac_c_werror_flag=$cu_save_c_werror_flag +AC_MSG_CHECKING([if __get_cpuid available]) +AC_COMPILE_IFELSE( + [AC_LANG_SOURCE([[ + #include + + int main(void) + { + unsigned int eax, ebx, ecx, edx; + __get_cpuid(1, &eax, &ebx, &ecx, &edx); + return 1; + } + ]]) + ],[ + AC_MSG_RESULT([yes]) + AC_DEFINE([HAVE_CPUID], [1], [__get_cpuid available]) + cpuid_exists=yes + ],[ + AC_MSG_RESULT([no]) + ]) + +ac_save_CFLAGS=$CFLAGS +CFLAGS="-mavx -mpclmul $CFLAGS" +AC_MSG_CHECKING([if pclmul intrinsic exists]) +AC_COMPILE_IFELSE( + [AC_LANG_SOURCE([[ + #include + + int main(void) + { + __m128i a, b; + a = _mm_clmulepi64_si128(a, b, 0x00); + return 1; + } + ]]) + ],[ + AC_MSG_RESULT([yes]) + AC_DEFINE([HAVE_PCLMUL_INTRINSIC], [1], [pclmul intrinsic exists]) + pclmul_intrinsic_exists=yes + ],[ + AC_MSG_RESULT([no]) + ]) +if test "x$cpuid_exists" = "xyes" && + test "x$pclmul_intrinsic_exists" = "xyes"; then + AC_DEFINE([USE_PCLMUL_CRC32], [1], + [CRC32 calculation by pclmul hardware instruction enabled]) +fi +AM_CONDITIONAL([USE_PCLMUL_CRC32], + [test "x$cpuid_exists" = "xyes" && + test "x$pclmul_intrinsic_exists" = "xyes"]) +CFLAGS=$ac_save_CFLAGS + ############################################################################ dnl Autogenerated by the 'gen-lists-of-programs.sh' auxiliary script. -- cgit v1.2.1