From 7b3783da12d7260911cf1b8e7ad445ea5e6e3e9b Mon Sep 17 00:00:00 2001 From: Victor Julien Date: Tue, 5 Mar 2024 13:06:08 +0530 Subject: [PATCH] detect: optimize sig_cnt setting Utilize _popcnt64 where available. (cherry picked from commit c4ac6cd) --- configure.ac | 5 +++++ src/detect-engine-siggroup.c | 32 ++++++++++++++++++++++++++------ src/suricata.c | 3 +++ 3 files changed, 34 insertions(+), 6 deletions(-) diff --git a/configure.ac b/configure.ac index 72629f422d..04305ecd95 100644 --- a/configure.ac +++ b/configure.ac @@ -219,6 +219,11 @@ [], [ #include ]) + AC_CHECK_DECL([_popcnt64], + AC_DEFINE([HAVE_POPCNT64], [1], [Use _popcnt64]), + [], [ + #include + ]) OCFLAGS=$CFLAGS CFLAGS="" diff --git a/src/detect-engine-siggroup.c b/src/detect-engine-siggroup.c index a87084916f..f47b19234f 100644 --- a/src/detect-engine-siggroup.c +++ b/src/detect-engine-siggroup.c @@ -440,6 +440,24 @@ error: return -1; } +#ifdef HAVE_POPCNT64 +#include +static uint32_t Popcnt(const uint8_t *array, const uint32_t size) +{ + /* input needs to be a multiple of 8 for u64 casts to work */ + DEBUG_VALIDATE_BUG_ON(size < 8); + DEBUG_VALIDATE_BUG_ON(size % 8); + + uint32_t cnt = 0; + uint64_t *ptr = (uint64_t *)array; + for (uint64_t idx = 0; idx < size; idx += 8) { + cnt += _popcnt64(*ptr); + ptr++; + } + return cnt; +} +#endif + /** * \brief Updates the SigGroupHead->sig_cnt with the total count of all the * Signatures present in this SigGroupHead. @@ -450,14 +468,16 @@ error: */ void SigGroupHeadSetSigCnt(SigGroupHead *sgh, uint32_t max_idx) { - uint32_t sig; - - sgh->init->sig_cnt = 0; - for (sig = 0; sig < max_idx + 1; sig++) { +#ifdef HAVE_POPCNT64 + sgh->init->sig_cnt = Popcnt(sgh->init->sig_array, sgh->init->sig_size); +#else + uint32_t cnt = 0; + for (uint32_t sig = 0; sig < max_idx + 1; sig++) { if (sgh->init->sig_array[sig / 8] & (1 << (sig % 8))) - sgh->init->sig_cnt++; + cnt++; } - + sgh->init->sig_cnt = cnt; +#endif return; } diff --git a/src/suricata.c b/src/suricata.c index 72aa927e47..6057b82e94 100644 --- a/src/suricata.c +++ b/src/suricata.c @@ -767,6 +767,9 @@ static void PrintBuildInfo(void) strlcat(features, "RUST ", sizeof(features)); #if defined(SC_ADDRESS_SANITIZER) strlcat(features, "ASAN ", sizeof(features)); +#endif +#if defined(HAVE_POPCNT64) + strlcat(features, "POPCNT64 ", sizeof(features)); #endif if (strlen(features) == 0) { strlcat(features, "none", sizeof(features)); -- 2.47.3