diff --git a/Code/Framework/AzCore/AzCore/Jobs/JobManagerComponent.cpp b/Code/Framework/AzCore/AzCore/Jobs/JobManagerComponent.cpp index 2cd740bf9e..e98711049c 100644 --- a/Code/Framework/AzCore/AzCore/Jobs/JobManagerComponent.cpp +++ b/Code/Framework/AzCore/AzCore/Jobs/JobManagerComponent.cpp @@ -20,8 +20,9 @@ #include -AZ_CVAR(uint32_t, cl_numeratorJobThreads, 1, nullptr, AZ::ConsoleFunctorFlags::Null, "Legacy Job system multiplier on the number of hw threads the machine supports to create at initialization"); -AZ_CVAR(uint32_t, cl_denominatorJobThreads, 2, nullptr, AZ::ConsoleFunctorFlags::Null, "Legacy Job system divisor on the number of hw threads the machine supports to create at initialization"); +AZ_CVAR(float, cl_jobThreadsConcurrencyRatio, 0.5f, nullptr, AZ::ConsoleFunctorFlags::Null, "Legacy Job system multiplier on the number of hw threads the machine creates at initialization"); +AZ_CVAR(uint32_t, cl_jobThreadsNumReserved, 2, nullptr, AZ::ConsoleFunctorFlags::Null, "Legacy Job system number of hardware threads that are reserved for O3DE system threads"); +AZ_CVAR(uint32_t, cl_jobThreadsMinNumber, 2, nullptr, AZ::ConsoleFunctorFlags::Null, "Legacy Job system minimum number of worker threads to create after scaling the number of hw threads"); namespace AZ { @@ -53,7 +54,11 @@ namespace AZ int numberOfWorkerThreads = m_numberOfWorkerThreads; if (numberOfWorkerThreads <= 0) // spawn default number of threads { - numberOfWorkerThreads = AZ::GetMin(static_cast(desc.m_workerThreads.capacity()), cl_numeratorJobThreads * AZStd::thread::hardware_concurrency() / cl_denominatorJobThreads); + // calc number of job threads = cl_jobThreadsConcurrencyRatio * (number of hardware threads - cl_jobThreadsNumReserved), + // min = cl_jobThreadsMinNumber, + // max = number of hardware threads - cl_jobThreadsNumReserved + uint32_t scaledHardwareThreads = AZ::GetMax( cl_jobThreadsMinNumber, static_cast(AZStd::floor( 0.5f + AZ::GetClamp(cl_jobThreadsConcurrencyRatio, 0.0f, 1.0f) * static_cast(AZStd::thread::hardware_concurrency() - cl_jobThreadsNumReserved)))); + numberOfWorkerThreads = AZ::GetMin(static_cast(desc.m_workerThreads.capacity()), scaledHardwareThreads); #if (AZ_TRAIT_MAX_JOB_MANAGER_WORKER_THREADS) numberOfWorkerThreads = AZ::GetMin(numberOfWorkerThreads, AZ_TRAIT_MAX_JOB_MANAGER_WORKER_THREADS); #endif // (AZ_TRAIT_MAX_JOB_MANAGER_WORKER_THREADS) diff --git a/Code/Framework/AzCore/AzCore/Task/TaskGraphSystemComponent.cpp b/Code/Framework/AzCore/AzCore/Task/TaskGraphSystemComponent.cpp index 198969dbce..6548d9d162 100644 --- a/Code/Framework/AzCore/AzCore/Task/TaskGraphSystemComponent.cpp +++ b/Code/Framework/AzCore/AzCore/Task/TaskGraphSystemComponent.cpp @@ -11,11 +11,13 @@ #include #include #include +#include // Create a cvar as a central location for experimentation with switching from the Job system to TaskGraph system. AZ_CVAR(bool, cl_activateTaskGraph, false, nullptr, AZ::ConsoleFunctorFlags::Null, "Flag clients of TaskGraph to switch between jobs/taskgraph (Note does not disable task graph system)"); -AZ_CVAR(uint32_t, cl_numeratorTaskGraphThreads, 3, nullptr, AZ::ConsoleFunctorFlags::Null, "TaskGraph multiplier on the number of hw threads the machine supports to create at initialization"); -AZ_CVAR(uint32_t, cl_denominatorTaskGraphThreads, 4, nullptr, AZ::ConsoleFunctorFlags::Null, "TaskGraph divisor on the number of hw threads the machine supports to create at initialization"); +AZ_CVAR(float, cl_taskGraphThreadsConcurrencyRatio, 0.75f, nullptr, AZ::ConsoleFunctorFlags::Null, "TaskGraph calculate the number of worker threads to spawn by scaling the number of hw threads, value is clamped between 0.0f and 1.0f"); +AZ_CVAR(uint32_t, cl_taskGraphThreadsNumReserved, 2, nullptr, AZ::ConsoleFunctorFlags::Null, "TaskGraph number of hardware threads that are reserved for O3DE system threads"); +AZ_CVAR(uint32_t, cl_taskGraphThreadsMinNumber, 2, nullptr, AZ::ConsoleFunctorFlags::Null, "TaskGraph minimum number of worker threads to create after scaling the number of hw threads"); static constexpr uint32_t TaskExecutorServiceCrc = AZ_CRC_CE("TaskExecutorService"); @@ -27,10 +29,13 @@ namespace AZ if (Interface::Get() == nullptr) { - uint32_t numThreads = cl_numeratorTaskGraphThreads * AZStd::thread::hardware_concurrency() / cl_denominatorTaskGraphThreads; - m_taskExecutor = aznew TaskExecutor(numThreads); + // calc number of worker threads = cl_taskGraphThreadsConcurrencyRatio * (number of hardware threads - cl_taskGraphThreadsNumReserved), + // min = cl_taskGraphThreadsMinNumber, + // max = number of hardware threads - cl_taskGraphThreadsNumReserved + uint32_t scaledHardwareThreads = AZ::GetMax( cl_taskGraphThreadsMinNumber, static_cast(AZStd::floor( 0.5f + AZ::GetClamp(cl_taskGraphThreadsConcurrencyRatio, 0.0f, 1.0f) * static_cast(AZStd::thread::hardware_concurrency() - cl_taskGraphThreadsNumReserved)))); + m_taskExecutor = aznew TaskExecutor(scaledHardwareThreads); TaskExecutor::SetInstance(m_taskExecutor); - Interface::Register(this); + Interface::Register(this); } }