diff options
| author | Stefan Boberg <[email protected]> | 2025-10-10 18:09:53 +0200 |
|---|---|---|
| committer | GitHub Enterprise <[email protected]> | 2025-10-10 18:09:53 +0200 |
| commit | c4801320150ea0c492cf343d490a0a339432f060 (patch) | |
| tree | d3013ef82c1707e38db3abac94d1fec0ca352394 /src/zenutil/workerpools.cpp | |
| parent | shorten thread pool names for Linux which has a limit of 15 characters (#563) (diff) | |
| download | zen-c4801320150ea0c492cf343d490a0a339432f060.tar.xz zen-c4801320150ea0c492cf343d490a0a339432f060.zip | |
add ability to limit concurrency (#565)
effective concurrency in zenserver can be limited via the `--corelimit=<N>` option on the command line. Any value passed in here will be used instead of the return value from `std::thread::hardware_concurrency()` if it is lower.
* added --corelimit option to zenserver
* made sure thread pools are configured lazily and not during global init
* added log output indicating effective and HW concurrency
* added change log entry
* removed debug logging from ZenEntryPoint::Run()
also removed main thread naming on Linux since it makes the output from `top` and similar tools confusing (it shows `main` instead of `zenserver`)
Diffstat (limited to 'src/zenutil/workerpools.cpp')
| -rw-r--r-- | src/zenutil/workerpools.cpp | 115 |
1 files changed, 68 insertions, 47 deletions
diff --git a/src/zenutil/workerpools.cpp b/src/zenutil/workerpools.cpp index 55c91e68e..1bab39b2a 100644 --- a/src/zenutil/workerpools.cpp +++ b/src/zenutil/workerpools.cpp @@ -11,98 +11,119 @@ ZEN_THIRD_PARTY_INCLUDES_END namespace zen { namespace { - const int LargeWorkerThreadPoolTreadCount = gsl::narrow<int>(Max(std::thread::hardware_concurrency() - 1u, 2u)); - const int MediumWorkerThreadPoolTreadCount = gsl::narrow<int>(Max((std::thread::hardware_concurrency() / 4u), 2u)); - const int SmallWorkerThreadPoolTreadCount = gsl::narrow<int>(Max((std::thread::hardware_concurrency() / 8u), 1u)); - const int TinyWorkerThreadPoolTreadCount = 1; - static bool IsShutDown = false; + struct WorkerPools + { + const int LargeWorkerThreadPoolTreadCount = gsl::narrow<int>(Max(GetHardwareConcurrency() - 1u, 2u)); + const int MediumWorkerThreadPoolTreadCount = gsl::narrow<int>(Max((GetHardwareConcurrency() / 4u), 2u)); + const int SmallWorkerThreadPoolTreadCount = gsl::narrow<int>(Max((GetHardwareConcurrency() / 8u), 1u)); + const int TinyWorkerThreadPoolTreadCount = 1; - RwLock PoolLock; + bool IsShutDown = false; - struct WorkerPool - { - std::unique_ptr<WorkerThreadPool> Pool; - const int TreadCount; - const std::string_view Name; - }; + RwLock PoolLock; - WorkerPool BurstLargeWorkerPool = {.TreadCount = LargeWorkerThreadPoolTreadCount, .Name = "large"}; - WorkerPool BackgroundLargeWorkerPool = {.TreadCount = LargeWorkerThreadPoolTreadCount, .Name = "large_bg"}; + struct WorkerPool + { + std::unique_ptr<WorkerThreadPool> Pool; + const int TreadCount; + const std::string_view Name; + }; - WorkerPool BurstMediumWorkerPool = {.TreadCount = MediumWorkerThreadPoolTreadCount, .Name = "medium"}; - WorkerPool BackgroundMediumWorkerPool = {.TreadCount = MediumWorkerThreadPoolTreadCount, .Name = "medium_bg"}; + WorkerPool BurstLargeWorkerPool = {.TreadCount = LargeWorkerThreadPoolTreadCount, .Name = "large"}; + WorkerPool BackgroundLargeWorkerPool = {.TreadCount = LargeWorkerThreadPoolTreadCount, .Name = "large_bg"}; - WorkerPool BurstSmallWorkerPool = {.TreadCount = SmallWorkerThreadPoolTreadCount, .Name = "small"}; - WorkerPool BackgroundSmallWorkerPool = {.TreadCount = SmallWorkerThreadPoolTreadCount, .Name = "small_bg"}; + WorkerPool BurstMediumWorkerPool = {.TreadCount = MediumWorkerThreadPoolTreadCount, .Name = "medium"}; + WorkerPool BackgroundMediumWorkerPool = {.TreadCount = MediumWorkerThreadPoolTreadCount, .Name = "medium_bg"}; - WorkerPool BurstTinyWorkerPool = {.TreadCount = TinyWorkerThreadPoolTreadCount, .Name = "tiny"}; - WorkerPool BackgroundTinyWorkerPool = {.TreadCount = TinyWorkerThreadPoolTreadCount, .Name = "tiny_bg"}; + WorkerPool BurstSmallWorkerPool = {.TreadCount = SmallWorkerThreadPoolTreadCount, .Name = "small"}; + WorkerPool BackgroundSmallWorkerPool = {.TreadCount = SmallWorkerThreadPoolTreadCount, .Name = "small_bg"}; - WorkerPool SyncWorkerPool = {.TreadCount = 0, .Name = "synctp"}; + WorkerPool BurstTinyWorkerPool = {.TreadCount = TinyWorkerThreadPoolTreadCount, .Name = "tiny"}; + WorkerPool BackgroundTinyWorkerPool = {.TreadCount = TinyWorkerThreadPoolTreadCount, .Name = "tiny_bg"}; - WorkerThreadPool& EnsurePoolPtr(WorkerPool& Pool) - { + WorkerPool SyncWorkerPool = {.TreadCount = 0, .Name = "synctp"}; + + WorkerThreadPool& EnsurePoolPtr(WorkerPool& Pool) { - RwLock::SharedLockScope _(PoolLock); - if (Pool.Pool) { - return *Pool.Pool; + RwLock::SharedLockScope _(PoolLock); + if (Pool.Pool) + { + return *Pool.Pool; + } } + RwLock::ExclusiveLockScope _(PoolLock); + ZEN_ASSERT(!IsShutDown); + if (!Pool.Pool) + { + Pool.Pool.reset(new WorkerThreadPool(Pool.TreadCount, Pool.Name)); + } + return *Pool.Pool; } - RwLock::ExclusiveLockScope _(PoolLock); - ZEN_ASSERT(!IsShutDown); - if (!Pool.Pool) + + void Shutdown() { - Pool.Pool.reset(new WorkerThreadPool(Pool.TreadCount, Pool.Name)); + RwLock::ExclusiveLockScope _(PoolLock); + IsShutDown = true; + BurstLargeWorkerPool.Pool.reset(); + BackgroundLargeWorkerPool.Pool.reset(); + BurstMediumWorkerPool.Pool.reset(); + BackgroundMediumWorkerPool.Pool.reset(); + BurstSmallWorkerPool.Pool.reset(); + BackgroundSmallWorkerPool.Pool.reset(); + BurstTinyWorkerPool.Pool.reset(); + BackgroundTinyWorkerPool.Pool.reset(); + SyncWorkerPool.Pool.reset(); } - return *Pool.Pool; + }; + + WorkerPools& Pools() + { + static WorkerPools _; + return _; } + } // namespace WorkerThreadPool& GetLargeWorkerPool(EWorkloadType WorkloadType) { - return EnsurePoolPtr(WorkloadType == EWorkloadType::Burst ? BurstLargeWorkerPool : BackgroundLargeWorkerPool); + auto& p = Pools(); + return p.EnsurePoolPtr(WorkloadType == EWorkloadType::Burst ? p.BurstLargeWorkerPool : p.BackgroundLargeWorkerPool); } WorkerThreadPool& GetMediumWorkerPool(EWorkloadType WorkloadType) { - return EnsurePoolPtr(WorkloadType == EWorkloadType::Burst ? BurstMediumWorkerPool : BackgroundMediumWorkerPool); + auto& p = Pools(); + return p.EnsurePoolPtr(WorkloadType == EWorkloadType::Burst ? p.BurstMediumWorkerPool : p.BackgroundMediumWorkerPool); } WorkerThreadPool& GetSmallWorkerPool(EWorkloadType WorkloadType) { - return EnsurePoolPtr(WorkloadType == EWorkloadType::Burst ? BurstSmallWorkerPool : BackgroundSmallWorkerPool); + auto& p = Pools(); + return p.EnsurePoolPtr(WorkloadType == EWorkloadType::Burst ? p.BurstSmallWorkerPool : p.BackgroundSmallWorkerPool); } WorkerThreadPool& GetTinyWorkerPool(EWorkloadType WorkloadType) { - return EnsurePoolPtr(WorkloadType == EWorkloadType::Burst ? BurstTinyWorkerPool : BackgroundTinyWorkerPool); + auto& p = Pools(); + return p.EnsurePoolPtr(WorkloadType == EWorkloadType::Burst ? p.BurstTinyWorkerPool : p.BackgroundTinyWorkerPool); } WorkerThreadPool& GetSyncWorkerPool() { - return EnsurePoolPtr(SyncWorkerPool); + auto& p = Pools(); + return p.EnsurePoolPtr(p.SyncWorkerPool); } void ShutdownWorkerPools() { - RwLock::ExclusiveLockScope _(PoolLock); - IsShutDown = true; - BurstLargeWorkerPool.Pool.reset(); - BackgroundLargeWorkerPool.Pool.reset(); - BurstMediumWorkerPool.Pool.reset(); - BackgroundMediumWorkerPool.Pool.reset(); - BurstSmallWorkerPool.Pool.reset(); - BackgroundSmallWorkerPool.Pool.reset(); - BurstTinyWorkerPool.Pool.reset(); - BackgroundTinyWorkerPool.Pool.reset(); - SyncWorkerPool.Pool.reset(); + Pools().Shutdown(); } } // namespace zen |