콘텐츠로 이동

UE5 Unreal Insights 프로파일링

Unreal Insights는 UE5에 내장된 실시간 성능 분석 도구입니다. 별도 서드파티 프로파일러 없이 CPU 타이밍, 메모리 할당, GPU 프레임, 네트워크 패킷을 수집하고 시각화합니다.

주요 분석 채널:

  • Timing Insights: CPU/GPU 프레임 타임, 스레드별 작업 분석
  • Memory Insights: 힙 할당 추적, 메모리 증가 지점 탐지
  • Network Insights: 패킷 크기, 리플리케이션 비용 분석
  • Asset Loading: 에셋 로딩 타임라인

창 → Unreal Insights → Session Browser
또는 상단 툴바 → Trace 버튼
Terminal window
# 게임 실행 시 트레이스 활성화
MyGame.exe -trace=cpu,memory,log,bookmark -tracehost=127.0.0.1
# 특정 채널 지정
MyGame.exe -trace=cpu,gpu,frame,rhicommands
#include "ProfilingDebugging/CsvProfiler.h"
#include "Trace/Trace.h"
// 커스텀 카테고리 정의
UE_TRACE_CHANNEL_DEFINE(GameplayChannel)
// 특정 구간 마킹
void MyGameMode::StartRound()
{
// Insights에 북마크 추가
TRACE_BOOKMARK(TEXT("RoundStart"));
// CSV 프로파일링 시작
CSV_EVENT(Basic, TEXT("RoundStart"));
}

// 헤더에 Stat 그룹 선언
DECLARE_STATS_GROUP(TEXT("MyGame"), STATGROUP_MyGame, STATCAT_Advanced);
// 사이클 카운터: 코드 구간 실행 시간 측정
DECLARE_CYCLE_STAT(TEXT("UpdateEnemyAI"), STAT_UpdateEnemyAI, STATGROUP_MyGame);
DECLARE_CYCLE_STAT(TEXT("ProcessCombat"), STAT_ProcessCombat, STATGROUP_MyGame);
// 메모리 카운터
DECLARE_MEMORY_STAT(TEXT("EnemyPoolMemory"), STAT_EnemyPoolMemory, STATGROUP_MyGame);
// 일반 카운터
DECLARE_DWORD_COUNTER_STAT(TEXT("ActiveEnemies"), STAT_ActiveEnemies, STATGROUP_MyGame);
// 실제 사용
void AEnemyManager::UpdateEnemyAI()
{
SCOPE_CYCLE_COUNTER(STAT_UpdateEnemyAI); // 함수 전체 시간 측정
for (AEnemy* Enemy : _activeEnemies)
{
{
SCOPE_CYCLE_COUNTER(STAT_ProcessCombat);
Enemy->UpdateCombat();
}
}
// 카운터 업데이트
SET_DWORD_STAT(STAT_ActiveEnemies, _activeEnemies.Num());
}
// 메모리 Stat 갱신
void AEnemyManager::OnEnemyPoolResized(int64 NewSize)
{
SET_MEMORY_STAT(STAT_EnemyPoolMemory, NewSize);
}

게임 실행 중 콘솔(`)에 입력합니다.

stat fps — 프레임 레이트 표시
stat unit — 게임 스레드·렌더 스레드·GPU 시간
stat game — 게임 스레드 세부 분석
stat scenerendering — 렌더링 통계
stat memory — 메모리 사용량
stat MyGame — 커스텀 Stat 그룹 표시
stat startfile — .utrace 파일 기록 시작
stat stopfile — 기록 중지

Timing Insights → Frames 뷰
→ 튀는(spike) 프레임 클릭
→ CPU Tracks에서 긴 구간 확인
→ 해당 함수 더블클릭 → 소스로 이동
지표기준원인
GameThread > 33ms60fps 불가복잡한 Tick, 물리
RenderThread > 33msGPU 대기드로우콜, 셰이더
GPU > 33ms렌더 병목폴리곤, 텍스처
Hitch > 100ms눈에 띄는 끊김에셋 로딩, GC
// 특정 프레임 지연 감지 및 로깅
class FHitchDetector
{
public:
void Tick(float DeltaTime)
{
const float HitchThreshold = 0.1f; // 100ms
if (DeltaTime > HitchThreshold)
{
UE_LOG(LogTemp, Warning,
TEXT("Hitch detected: %.1f ms"), DeltaTime * 1000.f);
// 트레이스에 북마크 추가
TRACE_BOOKMARK(TEXT("Hitch"));
}
}
};

// 메모리 할당 추적 활성화
// 실행 인수: -trace=memory
// LLM(Low Level Memory) 태그로 메모리 분류
#include "HAL/LowLevelMemTracker.h"
LLM_SCOPE(ELLMTag::GameplayTags);
// 이 범위 내 할당은 GameplayTags 카테고리로 추적
// 커스텀 LLM 태그 정의
LLM_DECLARE_TAG(MySystem);
// 사용
LLM_SCOPE_BYTAG(MySystem);
auto* Data = new FMyData();
Memory Insights → Allocations 뷰
→ 시간 범위 선택 (메모리가 증가하는 구간)
→ "Alive Allocations" 필터
→ 호출 스택으로 누수 지점 확인

// CSV 카테고리 등록
CSV_DEFINE_CATEGORY(MyGame, true);
// 프레임마다 기록
void AGameMode::Tick(float DeltaTime)
{
CSV_CUSTOM_STAT(MyGame, ActiveEnemies,
EnemyManager->GetActiveCount(), ECsvCustomStatOp::Set);
CSV_CUSTOM_STAT(MyGame, FrameTime,
DeltaTime * 1000.f, ECsvCustomStatOp::Set);
}
Terminal window
# CSV 기록 실행
MyGame.exe -csvGPUStats -csvCategories=MyGame -dumpCSV=Profiling/session.csv

// 성능 예산 초과 시 경고
void AGameMode::CheckPerformanceBudget()
{
const float TargetFrameTime = 1.f / 60.f; // 16.67ms
float GameThreadTime = FApp::GetCurrentTime() - FApp::GetLastTime();
if (GameThreadTime > TargetFrameTime * 1.5f)
{
UE_LOG(LogTemp, Warning,
TEXT("Performance budget exceeded: %.2f ms (budget: %.2f ms)"),
GameThreadTime * 1000.f, TargetFrameTime * 1000.f);
}
}

FProfilerRecorder — 런타임 경량 수치 수집

섹션 제목: “FProfilerRecorder — 런타임 경량 수치 수집”

Unreal Insights 없이 특정 수치를 런타임에 빠르게 기록하고 화면에 표시할 때 사용하는 패턴입니다.

// 커스텀 런타임 성능 HUD 예제
class FRuntimePerfHUD
{
struct FFrame { float GameMs; float RenderMs; float GpuMs; };
TArray<FFrame> Frames;
bool bRecording = false;
public:
void StartRecording() { bRecording = true; Frames.Empty(); }
void Tick(float DeltaSeconds)
{
if (!bRecording) return;
Frames.Add({
FPlatformTime::ToMilliseconds(GGameThreadTime),
FPlatformTime::ToMilliseconds(GRenderThreadTime),
FPlatformTime::ToMilliseconds(GGPUFrameTime)
});
}
// HUD DrawHUD 오버라이드에서 호출
void DisplayOnScreen(UCanvas* Canvas)
{
if (Frames.IsEmpty()) return;
const FFrame& F = Frames.Last();
Canvas->DrawText(GEngine->GetLargeFont(),
FString::Printf(TEXT("GT %.1f RT %.1f GPU %.1f ms"),
F.GameMs, F.RenderMs, F.GpuMs),
10.f, 50.f);
}
TArray<FFrame> StopRecording() { bRecording = false; return Frames; }
};

CSV 세션 비교 — 성능 회귀 자동 감지

섹션 제목: “CSV 세션 비교 — 성능 회귀 자동 감지”

두 빌드의 CSV를 비교해 회귀를 감지하는 CI 파이프라인 예시입니다.

Terminal window
# 빌드 A 프로파일 수집
MyGame-A.exe -csvGPUStats -csvCategories=MyGame -dumpCSV=build_A.csv -ExecCmds="automation RunTests Game.Perf; quit"
# 빌드 B 프로파일 수집
MyGame-B.exe -csvGPUStats -csvCategories=MyGame -dumpCSV=build_B.csv -ExecCmds="automation RunTests Game.Perf; quit"
# Python으로 평균 프레임 시간 비교
python CSVTools/CSVCompare.py build_A.csv build_B.csv \
--stat FrameTime --threshold 10 # 10% 초과 증가 시 CI 실패
항목설명
-csvGPUStatsGPU 통계도 CSV에 포함
-csvCategories수집할 카테고리 필터
-dumpCSV출력 파일 경로
CSVCompare.pyEpic 제공 비교 스크립트 (Engine/Extras/Python/)

도구용도
SCOPE_CYCLE_COUNTER코드 구간 CPU 시간 측정
stat 콘솔 명령어실시간 성능 모니터링
Timing Insights프레임별 CPU/GPU 분석
Memory Insights메모리 할당 추적
CSV Profiling자동화 성능 기록
TRACE_BOOKMARK중요 이벤트 마킹

프로파일링은 추측이 아닌 데이터 기반 최적화의 시작점입니다. Unreal Insights로 실제 병목을 확인한 후 최적화 작업을 진행해야 효과적입니다.