* 이 게시물에 대한 비판, 조언 모두 환영합니다.
작업을 하다 보면 한 틱에 이렇게 많은 연산을 해도 될까? 라는 고민을 할 때가 있다.
예를 들면 수십만 개의 Cell을 받아 Update를 해주어야 하는 경우이다. 이 Update는 굳이 한 번에 완료될 필요는 없고,
여러 틱에 걸쳐 해도 되는 작업이라도 가정해보자.
한 틱에 수십만 개의 Cell을 Update하면 게임이 멈춰버릴 것이며, 여기에 스레드를 할당하기는 싫다.
그렇다고 해서 임의로 한 틱에 Update할 Cell의 개수를 임의로 정하는 것도 말이 안된다. 몇 개가 적당하며, 모든 Cell의 Update가 동일한 연산일 보장도 없을 것이다.
이런 상황에서 Time-Slicing이 유용했다.
간략히 말하자면 한 틱에 작업을 수행할 시간을 정하고 그 시간 동안만 작업을 수행하도록 처리하는 것이다.
아래의 ATimeSlicingCounter Class는 테스트를 위해 짠 Actor를 상속한 클래스이다.
// Called every frame
void ATimeSlicingCounter::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
if (m_IsProcessing == true)
{
// 틱 증가
++m_TickCounter;
// 이전 작업량 캐싱
int32 PrevWorkCount = m_CurrentWorkCount;
// one tick, use 0.1ms
double RemainingTime = 0.0001f;
while (RemainingTime > 0.0f)
{
// 작업 시작 전 Time
const double StartTime = FPlatformTime::Seconds();
// Do work begin
++m_CurrentWorkCount;
// Do work end
// 작업 완료 후 Time
const double EndTime = FPlatformTime::Seconds();
// 남은 시간 감소
RemainingTime -= (EndTime - StartTime);
// 작업 완료
if (m_CurrentWorkCount >= m_TotalWorkCount)
{
break;
}
}
// 이번 틱에 수행한 작업량
const int32 ProcessedCount = m_CurrentWorkCount - PrevWorkCount;
// 지금까지의 작업 진행률
const float WorkPercent = (m_CurrentWorkCount / (float)m_TotalWorkCount) * 100.0f;
// 작업 완료
if (m_CurrentWorkCount >= m_TotalWorkCount)
{
m_IsProcessing = false;
UE_LOG(LogTemp, Log, TEXT("[TimeSlicing] Complete ! WorkPercent[%d], ProcessedCount[%d], TickCounter[%d]"), (int32)WorkPercent, m_CurrentWorkCount, m_TickCounter);
}
else
{
UE_LOG(LogTemp, Log, TEXT("[TimeSlicing] Continue.. WorkPercent[%d], Processed Count in tick[%d], RemainWorkCount[%d]")
, (int32)WorkPercent, ProcessedCount, m_TotalWorkCount - m_CurrentWorkCount);
}
}
}
위 코드의 실행 결과는 아래의 사진처럼 한 틱에 약 7500개씩, 27번의 틱에 걸쳐 작업을 완수했다.
[ 주의 ]
만약에 작업 수행 구간에 DrawDebug를 해주거나 Log를 심게 되면 성능이 현저히 낮아지기 때문에, 한 틱의 작업을 완수한 후에 디버깅 및 로그를 심는 것이 좋다.
불가피 하게 작업 수행 구간에 디버깅 용 코드가 들어가야 한다면 디버깅 용 코드 작업 수행 시간을 따로 계산하여 Remaining Time에 적용해 볼만 하겠지만 게임 자체가 버벅이거나 본래의 양만큼 작업이 수행되지 않는다.
'언리얼 개발자' 카테고리의 다른 글
[Unreal] Smooth Dynamic Spline using PathFinding Points (3) | 2022.12.24 |
---|---|
[Unreal] 비동기[Async] PathFinding (0) | 2022.12.22 |
[Unreal] PathFinding & Following Component 구현 (0) | 2022.12.18 |
[Unreal] <Path Finding & Following> 0.Overview (0) | 2022.09.22 |
[Unreal] Property Editor : 조건부로 변수 노출하기 (2) | 2022.09.20 |