Unreal : ParallelFor

최대 1 분 소요

Unreal 병렬For문

소스코드 : \Engine\Source\Runtime\Core\Public\Async\ParallelFor.h

코드에서 보면 GraphTask로 쓰레드를 만든다.

TGraphTask<FParallelForTask>::CreateTask().ConstructAndDispatchWhenReady(Data, AnyThreadTasks - 1);

- GraphTask는 종종 GameThread를 사용하기도 한다.

- 따라서 모든 Task가 멀티 쓰레드로 돌아가지 않을 수도 있음.

- 이는 곧 ParallelFor문의 Num Parameter가 많아도 성능이 크게 향상되지 않을 수도 있다.

- 실제로 ParallelFor문을 간단한 작업 용도로 사용하는 것을 권장하며, 큰 ThreadTask는 FRunnable을 상속받아 따로 쓰레드를 돌리는게 좋다.

그렇다면 어떻게 사용하는게 좋을까?

- 난 이것을 100개 가까이 되는 datatable을 파싱하기 위해 사용하였다.

1. 먼저 FPlatformProcess::SupportsMultithreading()으로 멀티쓰레드가 지원하는 디바이스 인지 체크
2. FPlatformMisc::NumberOfWorkerThreadsToSpawn()으로 현재 사용가능한 쓰레드 갯수를 얻어온다.
3. 이제 쓰레드갯수에 따라 Task를 나눈다.
예를들어, 100개의 datatable이 있다고 가정, worker thread가 8개라면? floor(100 / 8) = 13, 13개씩 나누어 파싱하는 구조로 하였다.
bool bSupportMultithread = FPlatformProcess::SupportsMultithreading();
const int taskNum = FPlatformMisc::NumberOfWorkerThreadsToSpawn();
const int divideEnd = FMath::FloorToInt(InTasks.Num() / taskNum);
ParallelFor(taskNum, [&](int InIndex)
{
  int startAt = InIndex * divideEnd;
  if (startAt >= InTasks.Num())
  {
    return;
  }
  int endAt = startAt + divideEnd;
  // lask task
  if (InIndex == (taskNum - 1))
  {
    endAt = InTasks.Num();
  }
  for (int i = startAt; i < endAt; ++i)
  {
    UDataTable* dataTable = Cast<UDataTable>(dataTables[i]);
    if (dataTable)
    {
      // parsing code
    }
  }
}, !bSupportMultithread);

태그:

카테고리:

업데이트: