]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
detect: optimize sig_cnt setting
authorVictor Julien <vjulien@oisf.net>
Mon, 26 Feb 2024 11:17:15 +0000 (12:17 +0100)
committerVictor Julien <victor@inliniac.net>
Mon, 4 Mar 2024 10:50:30 +0000 (11:50 +0100)
Utilize _popcnt64 where available.

configure.ac
src/detect-engine-siggroup.c
src/suricata.c

index c510e7fccb5d71ef99f13195a781d57e56574713..1c0a39a5ccf1aa7b641df0f1b2b8653360099525 100644 (file)
         [], [
             #include <sys/random.h> 
             ])
+    AC_CHECK_DECL([_popcnt64],
+        AC_DEFINE([HAVE_POPCNT64], [1], [Use _popcnt64]),
+        [], [
+            #include <x86intrin.h> 
+            ])
 
     AC_CHECK_HEADERS([malloc.h])
     AC_CHECK_DECL([malloc_trim],
index 4be0b1c264743db6e3ed546c1ec4fe33465ff3cb..b08218193a0074913223e9364ddb3cb84a3b7ad2 100644 (file)
@@ -437,6 +437,24 @@ error:
     return -1;
 }
 
+#ifdef HAVE_POPCNT64
+#include <x86intrin.h>
+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.
@@ -447,14 +465,17 @@ error:
  */
 void SigGroupHeadSetSigCnt(SigGroupHead *sgh, uint32_t max_idx)
 {
-    uint32_t sig;
     sgh->init->max_sig_id = MAX(max_idx, sgh->init->max_sig_id);
-    sgh->init->sig_cnt = 0;
-    for (sig = 0; sig < sgh->init->max_sig_id + 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 < sgh->init->max_sig_id + 1; sig++) {
         if (sgh->init->sig_array[sig / 8] & (1 << (sig % 8)))
-            sgh->init->sig_cnt++;
+            cnt++;
     }
-
+    sgh->init->sig_cnt = cnt;
+#endif
     return;
 }
 
index 213f6d95e9c3ef79bbe3bb740e89bfc4a1a64e3a..462537c14e87206b6b0955de4b393a805ef77dde 100644 (file)
@@ -765,6 +765,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));