diff --git a/scripts/base/frameworks/broker/main.bro b/scripts/base/frameworks/broker/main.bro index 0fdf289ee6..fb73f78d3c 100644 --- a/scripts/base/frameworks/broker/main.bro +++ b/scripts/base/frameworks/broker/main.bro @@ -56,9 +56,11 @@ export { ## control mechanisms). const congestion_queue_size = 200 &redef; - ## Max number of threads to use for Broker/CAF functionality. - ## Using zero will cause this to be automatically determined - ## based on number of available CPUs. + ## Max number of threads to use for Broker/CAF functionality. Setting to + ## zero implies using the value of BRO_BROKER_MAX_THREADS environment + ## variable, if set, or else typically defaults to 4 (actually 2 threads + ## when simply reading offline pcaps as there's not expected to be any + ## communication and more threads just adds more overhead). const max_threads = 0 &redef; ## Max number of microseconds for under-utilized Broker/CAF diff --git a/src/broker/Manager.cc b/src/broker/Manager.cc index 9712516b74..1d3696efa0 100644 --- a/src/broker/Manager.cc +++ b/src/broker/Manager.cc @@ -184,22 +184,29 @@ void Manager::InitPostScript() config.set("scheduler.max-threads", max_threads); else { - // On high-core-count systems, spawning one thread per core - // can lead to significant performance problems even if most - // threads are under-utilized. Related: - // https://github.com/actor-framework/actor-framework/issues/699 - if ( reading_pcaps ) - config.set("scheduler.max-threads", 2u); + auto max_threads_env = getenv("BRO_BROKER_MAX_THREADS"); + + if ( max_threads_env ) + config.set("scheduler.max-threads", atoi(max_threads_env)); else { - auto hc = std::thread::hardware_concurrency(); - - if ( hc > 8u ) - hc = 8u; - else if ( hc < 4u) - hc = 4u; - - config.set("scheduler.max-threads", hc); + // On high-core-count systems, letting CAF spawn a thread per core + // can lead to significant performance problems even if most + // threads are under-utilized. Related: + // https://github.com/actor-framework/actor-framework/issues/699 + if ( reading_pcaps ) + config.set("scheduler.max-threads", 2u); + else + // If the goal was to map threads to actors, 4 threads seems + // like a minimal default that could make sense -- the main + // actors that should be doing work are (1) the core, + // (2) the subscriber, (3) data stores (actually made of + // a frontend + proxy actor). Number of data stores may + // actually vary, but lumped togather for simplicity. A (4) + // may be CAF's multiplexing or other internals... + // 4 is also the minimum number that CAF uses by default, + // even for systems with less than 4 cores. + config.set("scheduler.max-threads", 4u); } }