From ea95e85755e771fa92794680082df18d571649d5 Mon Sep 17 00:00:00 2001 From: Eric Leblond Date: Thu, 26 Aug 2021 18:11:42 +0200 Subject: [PATCH] profiling: set sample rate to power of 2 For the rules profiling, we really want to limit the performance impact to the maximum. So let's use an hash size that is a power of 2. This will allow to not use the modulo operation that is costly and simply use a single binary operator. This code is only active for rules profiling so we are backward compatible. --- src/util-profiling.c | 17 ++++++++++++----- suricata.yaml.in | 6 +++--- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/src/util-profiling.c b/src/util-profiling.c index 818c2cc85d..d9ea5535ed 100644 --- a/src/util-profiling.c +++ b/src/util-profiling.c @@ -1420,7 +1420,7 @@ int SCProfileRuleStopCollection(void) thread_local int profiling_rules_entered = 0; int profiling_output_to_file = 0; static SC_ATOMIC_DECLARE(uint64_t, samples); -static int rate = 1; +static uint64_t rate = 0; /** * \brief Initialize profiling. @@ -1432,9 +1432,16 @@ void SCProfilingInit(void) (void)ConfGetInt("profiling.sample-rate", &rate_v); if (rate_v > 0 && rate_v < INT_MAX) { - rate = (int)rate_v; - if (rate != 1) - SCLogInfo("profiling runs for every %dth packet", rate); + int literal_rate = (int)rate_v; + for (int i = literal_rate; i >= 1; i--) { + /* If i is a power of 2 */ + if ((i & (i - 1)) == 0) { + rate = i - 1; + break; + } + } + if (rate != 0) + SCLogInfo("profiling runs for every %luth packet", rate + 1); else SCLogInfo("profiling runs for every packet"); } @@ -1444,7 +1451,7 @@ void SCProfilingInit(void) int SCProfileRuleStart(Packet *p) { uint64_t sample = SC_ATOMIC_ADD(samples, 1); - if (sample % rate == 0) { + if ((sample & rate) == 0) { p->flags |= PKT_PROFILE; return 1; } diff --git a/suricata.yaml.in b/suricata.yaml.in index 2245b65a0b..947a682682 100644 --- a/suricata.yaml.in +++ b/suricata.yaml.in @@ -1757,9 +1757,9 @@ luajit: # profiling: # Run profiling for every X-th packet. The default is 1, which means we - # profile every packet. If set to 1000, one packet is profiled for every - # 1000 received. - #sample-rate: 1000 + # profile every packet. If set to 1024, one packet is profiled for every + # 1024 received. The sample rate must be a power of 2. + #sample-rate: 1024 # rule profiling rules: -- 2.47.2