]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
detect: optimize group head bitarray handling
authorVictor Julien <vjulien@oisf.net>
Mon, 26 Feb 2024 10:28:53 +0000 (11:28 +0100)
committerVictor Julien <victor@inliniac.net>
Mon, 4 Mar 2024 10:50:30 +0000 (11:50 +0100)
During startup large rulesets use a lot of large bitarrays, that
are frequently merged (OR'd).

Optimize this using SSE2 _mm_or_si128.

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

index 8b783b90e48ad6d43ac4072dfdcefc18e7890b85..4be0b1c264743db6e3ed546c1ec4fe33465ff3cb 100644 (file)
@@ -378,6 +378,24 @@ int SigGroupHeadClearSigs(SigGroupHead *sgh)
     return 0;
 }
 
+#ifdef __SSE2__
+#include <emmintrin.h>
+static void MergeBitarrays(const uint8_t *src, uint8_t *dst, const uint32_t size)
+{
+#define BYTES 16
+    const uint8_t *srcptr = src;
+    uint8_t *dstptr = dst;
+    for (uint32_t i = 0; i < size; i += 16) {
+        __m128i s = _mm_load_si128((const __m128i *)srcptr);
+        __m128i d = _mm_load_si128((const __m128i *)dstptr);
+        d = _mm_or_si128(s, d);
+        _mm_store_si128((__m128i *)dstptr, d);
+        srcptr += BYTES;
+        dstptr += BYTES;
+    }
+}
+#endif
+
 /**
  * \brief Copies the bitarray holding the sids from the source SigGroupHead to
  *        the destination SigGroupHead.
@@ -391,8 +409,6 @@ int SigGroupHeadClearSigs(SigGroupHead *sgh)
  */
 int SigGroupHeadCopySigs(DetectEngineCtx *de_ctx, SigGroupHead *src, SigGroupHead **dst)
 {
-    uint32_t idx = 0;
-
     if (src == NULL || de_ctx == NULL)
         return 0;
 
@@ -401,11 +417,15 @@ int SigGroupHeadCopySigs(DetectEngineCtx *de_ctx, SigGroupHead *src, SigGroupHea
         if (*dst == NULL)
             goto error;
     }
+    DEBUG_VALIDATE_BUG_ON(src->init->sig_size != (*dst)->init->sig_size);
 
+#ifdef __SSE2__
+    MergeBitarrays(src->init->sig_array, (*dst)->init->sig_array, src->init->sig_size);
+#else
     /* do the copy */
-    for (idx = 0; idx < src->init->sig_size; idx++)
+    for (uint32_t idx = 0; idx < src->init->sig_size; idx++)
         (*dst)->init->sig_array[idx] = (*dst)->init->sig_array[idx] | src->init->sig_array[idx];
-
+#endif
     if (src->init->score)
         (*dst)->init->score = MAX((*dst)->init->score, src->init->score);
 
index 4749085e4fe761f376b982621ab1de6c3ff34233..213f6d95e9c3ef79bbe3bb740e89bfc4a1a64e3a 100644 (file)
@@ -782,6 +782,9 @@ static void PrintBuildInfo(void)
 #endif
 #if defined(__SSE3__)
     strlcat(features, "SSE_3 ", sizeof(features));
+#endif
+#if defined(__SSE2__)
+    strlcat(features, "SSE_2 ", sizeof(features));
 #endif
     if (strlen(features) == 0) {
         strlcat(features, "none", sizeof(features));