icon안동민 개발노트

프로파일링 도구 활용


 언리얼 엔진의 C++ 코드 성능을 분석하고 최적화하기 위해서는 다양한 프로파일링 도구를 효과적으로 활용해야 합니다.

 이 절에서는 내장 프로파일링 도구와 외부 도구를 활용한 성능 분석 및 최적화 방법을 살펴보겠습니다.

언리얼 인사이트(Unreal Insights) 사용법

 언리얼 인사이트는 언리얼 엔진 4.27 이상에서 제공하는 강력한 프로파일링 도구입니다.

  1. 활성화 : Project Settings > Engine > Performance > Unreal Insights 활성화
  2. 데이터 수집 : 게임 실행 시 -trace=frame,cpu,gpu,memory,net 명령줄 인자 추가
  3. 분석 : UnrealInsights.exe를 실행하여 수집된 데이터 분석

 예시 코드 (트레이스 이벤트 추가)

TRACE_CPUPROFILER_EVENT_SCOPE(TEXT("MyCustomEvent"));
// 프로파일링할 코드

인게임 프로파일러 활용 방법

 인게임 프로파일러를 사용하여 실시간으로 성능 데이터를 확인할 수 있습니다.

  1. 활성화 : ~ 키를 눌러 콘솔 열기, stat unitgraph 입력
  2. CPU, GPU, 메모리 사용량 실시간 모니터링

 커스텀 통계 추가

DECLARE_CYCLE_STAT(TEXT("My Custom Stat"), STAT_MyCustomStat, STATGROUP_Game);
 
void SomeFunction()
{
    SCOPE_CYCLE_COUNTER(STAT_MyCustomStat);
    // 측정할 코드
}

CPU, GPU, 메모리 프로파일링 기법

 CPU 프로파일링

  1. 프로파일러 마커 사용
SCOPE_CYCLE_COUNTER(STAT_MyCPUIntensiveTask);
// CPU 집약적인 작업
  1. 핫 함수 식별 : UnrealInsights의 CPU Usage 뷰 활용

 GPU 프로파일링

  1. RenderDoc 통합 사용
  2. 언리얼 엔진의 GPU Visualizer 활용: r.ProfileGPU 콘솔 명령어

 메모리 프로파일링

  1. 메모리 보고서 생성 : memreport -full 콘솔 명령어
  2. 언리얼 오브젝트의 메모리 사용량 추적:
FObjectMemoryAnalyzer MemAnalyzer(MyObject);
UE_LOG(LogTemp, Log, TEXT("Memory used: %d bytes"), MemAnalyzer.GetTotalUsage());

핫스팟 식별 및 분석 방법

  1. 프로파일링 데이터에서 가장 시간을 많이 소비하는 함수 식별
  2. 코드 리뷰 및 알고리즘 분석
  3. 최적화 가능성 평가

병목 현상 해결 전략

  1. 알고리즘 최적화
  2. 캐싱 활용
  3. 병렬 처리 도입

 예시 (캐싱 활용)

TMap<FString, FComputedData> DataCache;
 
FComputedData GetComputedData(const FString& Key)
{
    if (const FComputedData* CachedData = DataCache.Find(Key))
    {
        return *CachedData;
    }
    
    FComputedData NewData = ComputeExpensiveData(Key);
    DataCache.Add(Key, NewData);
    return NewData;
}

멀티스레드 코드 프로파일링 기법

  1. 스레드 뷰어 활용 : UnrealInsights의 Threading Insights
  2. 락 경합 분석 : 크리티컬 섹션 진입/퇴출 시간 측정
double EnterTime = FPlatformTime::Seconds();
CriticalSection.Lock();
double LockAcquireTime = FPlatformTime::Seconds() - EnterTime;
UE_LOG(LogTemp, Log, TEXT("Lock acquire time: %f ms"), LockAcquireTime * 1000.0);

프로파일링 데이터 해석 및 시각화 방법

  1. 프로파일링 차트 분석 : CPU / GPU 사용률, 메모리 사용량 추이
  2. 콜 그래프 해석 : 함수 호출 관계 및 실행 시간 분석
  3. 히트맵 활용 : 성능 문제 지점 시각화

성능 최적화 목표 설정 및 추적 전략

  1. 구체적이고 측정 가능한 성능 목표 설정 (예 : "로딩 시간 30% 단축")
  2. 지속적인 성능 측정 및 기록
  3. A/B 테스트를 통한 최적화 효과 검증

지속적인 성능 모니터링 시스템 구축

  1. 자동화된 성능 테스트 파이프라인 구축
  2. 성능 회귀 테스트 구현
  3. 성능 메트릭 대시보드 개발

 예시 (성능 테스트 자동화)

IMPLEMENT_SIMPLE_AUTOMATION_TEST(FPerformanceRegressionTest, "Performance.LoadingTime", EAutomationTestFlags::ApplicationContextMask | EAutomationTestFlags::ProductFilter)
 
bool FPerformanceRegressionTest::RunTest(const FString& Parameters)
{
    double StartTime = FPlatformTime::Seconds();
    // 성능 테스트 로직 (예: 레벨 로딩)
    double EndTime = FPlatformTime::Seconds();
    double LoadTime = EndTime - StartTime;
    
    TestTrue("Loading time should be less than 5 seconds", LoadTime < 5.0);
    return true;
}

다양한 플랫폼에 따른 프로파일링 접근 방식

 PC

  • 고성능 디버깅 도구 활용 (Visual Studio 프로파일러)
  • 다양한 하드웨어 구성 고려

 콘솔

  • 플랫폼 특화 프로파일링 도구 사용
  • 메모리 제약 고려

 모바일

  • 배터리 소모 및 열 발생 모니터링
  • 메모리 및 CPU / GPU 사용량 최적화에 중점

 플랫폼별 최적화 예시

##if PLATFORM_WINDOWS
    // PC 특화 최적화
##elif PLATFORM_PS4 || PLATFORM_XBOXONE
    // 콘솔 특화 최적화
##elif PLATFORM_IOS || PLATFORM_ANDROID
    // 모바일 특화 최적화
##endif

네트워크 성능 프로파일링

  1. 네트워크 트래픽 모니터링 : Wireshark 활용
  2. 패킷 최적화 : 중복 데이터 제거, 압축 적용
  3. 지연 시간 측정 및 최적화

 네트워크 성능 측정 예시

void AMeasureNetworkPerformance()
{
    float StartTime = FPlatformTime::Seconds();
    // 네트워크 작업 수행
    float EndTime = FPlatformTime::Seconds();
    float Latency = EndTime - StartTime;
    UE_LOG(LogTemp, Log, TEXT("Network operation latency: %f ms"), Latency * 1000.0f);
}

대규모 오픈 월드 게임의 성능 최적화 전략

  1. 레벨 스트리밍 최적화
  2. LOD (Level of Detail) 시스템 구현
  3. 오클루전 컬링 활용

 레벨 스트리밍 최적화 예시

void AMyOpenWorldManager::LoadAdjacentLevels(const FVector& PlayerLocation)
{
    for (const FName& LevelName : AdjacentLevels)
    {
        float Distance = CalculateDistanceToLevel(PlayerLocation, LevelName);
        if (Distance < StreamingDistance && !LoadedLevels.Contains(LevelName))
        {
            ULevelStreamingDynamic::LoadLevelInstance(GetWorld(), LevelName, PlayerLocation, FRotator::ZeroRotator);
            LoadedLevels.Add(LevelName);
        }
    }
}

 언리얼 엔진의 프로파일링 도구를 효과적으로 활용하면 게임의 성능을 크게 향상시킬 수 있습니다. 언리얼 인사이츠와 인게임 프로파일러를 통해 실시간으로 성능 데이터를 수집하고 분석할 수 있으며, CPU, GPU, 메모리 사용량을 세밀하게 모니터링할 수 있습니다.

 핫스팟 식별 및 병목 현상 해결은 성능 최적화의 핵심입니다. 프로파일링 데이터를 바탕으로 가장 큰 성능 저하를 일으키는 부분을 찾아내고, 알고리즘 개선, 캐싱 도입, 병렬 처리 등의 전략을 적용하여 해결할 수 있습니다.

 멀티스레드 코드의 프로파일링은 특별한 주의가 필요합니다. 스레드 간 락 경합이나 동기화 문제를 식별하고 해결하는 것이 중요합니다. 언리얼 인사이츠의 Threading Insights 도구를 활용하면 이러한 문제를 효과적으로 분석할 수 있습니다.

 지속적인 성능 모니터링 시스템을 구축하는 것도 중요합니다. 자동화된 성능 테스트와 회귀 테스트를 통해 코드 변경이 전체 시스템 성능에 미치는 영향을 지속적으로 추적할 수 있습니다.

 다양한 플랫폼에 대한 최적화는 각 플랫폼의 특성을 고려해야 합니다. PC, 콘솔, 모바일 등 각 플랫폼마다 다른 제약 사항과 최적화 포인트가 있으므로, 플랫폼별 접근 방식을 달리해야 합니다.

 네트워크 성능 프로파일링은 온라인 게임에서 특히 중요합니다. 패킷 최적화, 지연 시간 측정 및 개선 등을 통해 네트워크 성능을 향상시킬 수 있습니다.

 대규모 오픈 월드 게임의 경우, 레벨 스트리밍, LOD 시스템, 오클루전 컬링 등의 기술을 적절히 활용하여 광활한 세계를 효율적으로 렌더링하고 관리해야 합니다.

 마지막으로, 프로파일링과 최적화는 지속적인 과정이라는 점을 명심해야 합니다. 게임 개발 전 과정에 걸쳐 정기적으로 성능을 측정하고 최적화하는 습관을 들이는 것이 중요합니다. 이를 통해 최종적으로 부드럽고 반응성 좋은 게임 경험을 제공할 수 있습니다.