From: Victor Julien Date: Mon, 26 Feb 2024 10:28:53 +0000 (+0100) Subject: detect: optimize group head bitarray handling X-Git-Tag: suricata-8.0.0-beta1~1673 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=94b4619bb9de27e3aea37d5e549a4f7d19398368;p=thirdparty%2Fsuricata.git detect: optimize group head bitarray handling During startup large rulesets use a lot of large bitarrays, that are frequently merged (OR'd). Optimize this using SSE2 _mm_or_si128. --- diff --git a/src/detect-engine-siggroup.c b/src/detect-engine-siggroup.c index 8b783b90e4..4be0b1c264 100644 --- a/src/detect-engine-siggroup.c +++ b/src/detect-engine-siggroup.c @@ -378,6 +378,24 @@ int SigGroupHeadClearSigs(SigGroupHead *sgh) return 0; } +#ifdef __SSE2__ +#include +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); diff --git a/src/suricata.c b/src/suricata.c index 4749085e4f..213f6d95e9 100644 --- a/src/suricata.c +++ b/src/suricata.c @@ -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));