언리얼 엔진 프로세서 카운트 멀티플라이어 분석
기능
- WMI(Windows Management Instrumentation)을 사용해 물리 코어 개수를 알아냄
- mono 인 경우는 WMI 쿼리를 사용할 수 없어 논리 프로세서 개수 사용
- 하이퍼 쓰레드가 활성화된 경우(물리 코어 개수보다 논리 코어 개수가 많음)
- BuildConfigruation.ProcessorCountMultiplier 값이 설정되어 있다면 물리 코어 개수에 지정한 숫자 배수로 액션 수행
- 물리 코어 개수가 5개 이상부터 물리 코어 개수와 논리 코어 개수 평균 개수로 액션 수행
- 하이퍼 쓰레드가 비활성화된 경우 물리 코어 개수만큼 액션 수행
코드
https://github.com/EpicGames/UnrealEngine/blob/76085d1106078d8988e4404391428252ba1eb9a7/Engine/Source/Programs/UnrealBuildTool/System/LocalExecutor.cs
namespace UnrealBuildTool
{
class ActionThread
{
// ...
public override bool ExecuteActions(List<Action> Actions)
{
// Time to sleep after each iteration of the loop in order to not busy wait.
const float LoopSleepTime = 0.1f;
// Use WMI to figure out physical cores, excluding hyper threading.
int NumCores = Utils.GetPhysicalProcessorCount();
if (NumCores == -1)
{
NumCores = System.Environment.ProcessorCount;
}
// The number of actions to execute in parallel is trying to keep the CPU busy enough in presence of I/O stalls.
int MaxActionsToExecuteInParallel = 0;
if (NumCores < System.Environment.ProcessorCount && BuildConfiguration.ProcessorCountMultiplier != 1.0)
{
// The CPU has more logical cores than physical ones, aka uses hyper-threading.
// Use multiplier if provided
MaxActionsToExecuteInParallel = (int)(NumCores * BuildConfiguration.ProcessorCountMultiplier);
}
else if (NumCores < System.Environment.ProcessorCount && NumCores > 4)
{
// The CPU has more logical cores than physical ones, aka uses hyper-threading.
// Use average of logical and physical if we have "lots of cores"
MaxActionsToExecuteInParallel = (int)(NumCores + System.Environment.ProcessorCount) / 2;
}
// No hyper-threading. Only kicking off a task per CPU to keep machine responsive.
else
{
MaxActionsToExecuteInParallel = NumCores;
}
// ...
}
}
}