From acc2c2192ec477ebfca2dc63f9731181ff5ad0f8 Mon Sep 17 00:00:00 2001 From: stickz Date: Fri, 5 Jul 2024 09:48:27 -0400 Subject: [PATCH] libtorrent: Add CPU popcount support (#9) This commit adds a native c-implementation to calculate the population count of the bitfield. It may be faster for CPUs which don't support SSE instructions. This is disabled by default and must be enabled by configuring with `--enable-cpu-popcount`. --- libtorrent/configure.ac | 1 + libtorrent/rak/algorithm.h | 15 +++++++++++++++ libtorrent/scripts/common.m4 | 10 ++++++++++ 3 files changed, 26 insertions(+) diff --git a/libtorrent/configure.ac b/libtorrent/configure.ac index f9c5c4e99..a466f440e 100644 --- a/libtorrent/configure.ac +++ b/libtorrent/configure.ac @@ -108,6 +108,7 @@ AC_CHECK_FUNCS(posix_memalign) TORRENT_CHECK_MADVISE() TORRENT_CHECK_CACHELINE() TORRENT_CHECK_POPCOUNT() +TORRENT_CPU_POPCOUNT() TORRENT_CHECK_EXECINFO() TORRENT_CHECK_PTHREAD_SETNAME_NP() TORRENT_MINCORE() diff --git a/libtorrent/rak/algorithm.h b/libtorrent/rak/algorithm.h index ad8e71589..4afd2814a 100644 --- a/libtorrent/rak/algorithm.h +++ b/libtorrent/rak/algorithm.h @@ -156,8 +156,22 @@ make_base(_InputIter __first, _InputIter __last, _Ftor __ftor) { return __base; } +#if USE_CPU_POPCOUNT +inline int countBit1Fast(unsigned int n) { + n = (n & 0x55555555u) + ((n >> 1) & 0x55555555u); + n = (n & 0x33333333u) + ((n >> 2) & 0x33333333u); + n = (n & 0x0f0f0f0fu) + ((n >> 4) & 0x0f0f0f0fu); + n = (n & 0x00ff00ffu) + ((n >> 8) & 0x00ff00ffu); + n = (n & 0x0000ffffu) + ((n >>16) & 0x0000ffffu); + return n; +} +#endif + template inline int popcount_wrapper(T t) { +#if USE_CPU_POPCOUNT + return countBit1Fast(t); +#else #if USE_BUILTIN_POPCOUNT if (std::numeric_limits::digits <= std::numeric_limits::digits) return __builtin_popcount(t); @@ -174,6 +188,7 @@ inline int popcount_wrapper(T t) { return count; #endif +#endif } } diff --git a/libtorrent/scripts/common.m4 b/libtorrent/scripts/common.m4 index b6d051f58..d9a46059f 100644 --- a/libtorrent/scripts/common.m4 +++ b/libtorrent/scripts/common.m4 @@ -125,6 +125,16 @@ AC_DEFUN([TORRENT_CHECK_POPCOUNT], [ ]) ]) +AC_DEFUN([TORRENT_CPU_POPCOUNT], [ + AC_ARG_ENABLE(cpu-popcount, + AC_HELP_STRING([--enable-cpu-popcount], [Enable cpu-popcount [[default=check]]]), + [ + if test "$enableval" = "yes"; then + AC_DEFINE(USE_CPU_POPCOUNT, 1, Use CPU popcount.) + fi + ]) +]) + AC_DEFUN([TORRENT_CHECK_CACHELINE], [ AC_MSG_CHECKING(for cacheline)