Quick Reference
Unity Profiler는 target 기기의 Development Build에서 spike frame을 골라 CPU Usage의 Timeline·Hierarchy에서 CPU·GC.Alloc 경로를, GPU Usage 모듈에서 GPU timing을 확인합니다.
- 기준 버전은 Unity 6.5 (6000.5)입니다. Profiler는 “느리다”를 CPU, GPU, memory, rendering 같은 모듈과 특정 frame/marker로 나누는 출발점입니다.
- 타깃 기기에서 Development Build를 연결하고, warm-up 뒤 같은 플레이 구간을 Record합니다. Editor는 편집기 자체의 비용과 asset 상태가 섞이므로 최종 판단 기준이 아닙니다.
- 평균만 보지 말고 spike frame을 선택해 Timeline과 Hierarchy를 오가며 Main Thread, Render Thread,
GC.Alloc, physics, UI rebuild의 실제 호출 경로를 확인합니다.
Profiler 설정
- Record는 새 frame 데이터를 수집합니다. 원인을 찾을 구간만 짧게 녹화하고, 상황과 build 정보를 함께 저장합니다. 긴 무작정 녹화는 원하는 spike를 찾기 어렵게 만듭니다.
- CPU Usage 모듈은 Hierarchy에서 비용이 큰 marker를, Timeline에서 thread별 병렬·대기 관계를 봅니다. Hierarchy의 self time만 보고 상위 호출자의 실제 비용을 놓치지 않도록 Total과 Self를 구분합니다.
- Deep Profile은 managed method를 더 세밀하게 계측하지만 instrumentation overhead가 큽니다. 성능 수치를 확정하는 모드가 아니라, 일반 capture에서 찾은 작은 범위를 한 번 더 파는 진단 모드로 씁니다.
- Call Stacks는 특히
GC.Alloc의 호출 위치를 좁힐 때 유용합니다. 모든 marker에 항상 켜 두기보다 필요한 category와 짧은 재현 구간에만 켭니다. - GPU Usage 모듈은 target platform과 graphics API가 GPU timing을 지원할 때만 신뢰할 수 있습니다. 빈 그래프나 불완전한 sample을 CPU가 빠르다는 결론으로 쓰지 않습니다.
판독과 스크립트 연결
Profiler Timeline에서 튄 frame을 먼저 고르고 thread를 분리한 뒤, 그 frame의 Hierarchy를 읽습니다. 예를 들어 Main Thread의 BehaviourUpdate가 크면 개별 script와 UI 갱신을, Physics.Simulate가 크면 timestep·collider 수를, present 대기가 크면 GPU/frame pacing을 다음 도구로 확인합니다.
using Unity.Profiling;
using UnityEngine;
public sealed class EnemySearch : MonoBehaviour
{
private static readonly ProfilerMarker SearchMarker =
new ProfilerMarker("EnemySearch.FindNearest");
public Transform FindNearest(Transform[] candidates, Vector3 origin)
{
using (SearchMarker.Auto())
{
Transform nearest = null;
float nearestDistance = float.MaxValue;
foreach (Transform candidate in candidates)
{
float distance = Vector3.SqrMagnitude(candidate.position - origin);
if (distance < nearestDistance)
{
nearest = candidate;
nearestDistance = distance;
}
}
return nearest;
}
}
}ProfilerMarker.Auto()는using범위의 실행 시간을 custom marker로 남깁니다. 너무 미세한 함수마다 붙이면 marker 자체가 분석을 흐리므로, 실제로 비교할 시스템 경계에만 둡니다.ProfilerRecorder는 플레이 중 특정 counter/marker 값을 코드에서 수집할 때 씁니다. UI에 fps 숫자를 붙이기 위한 무분별한 recorder 생성보다, 자동 performance test나 개발용 경보처럼 수집 목적이 분명한 곳에 둡니다.GC.Alloc은 CPU Usage의 선택 frame과 thread별 column에서 찾습니다. allocation이 보이면 문자열 보간, LINQ, boxing, 매 frame collection 생성 같은 실제 호출 경로를 Call Stacks로 확인합니다.
자주 틀리는 부분
Deep Profile에서 나온 ms를 출시 성능으로 기록하면 안 됩니다. method instrumentation이 실행 경로와 timing에 영향을 줍니다. 일반 Development Build capture로 회귀 여부를 판정하고, Deep Profile은 원인 위치를 찾는 보조 증거로만 사용하세요.
frame 하나의 최고값만으로 최적화 효과를 판단하지 마세요. 동일 입력을 여러 번 재현해 median, p95, worst spike를 같이 기록해야 GC, shader warm-up, OS 간섭 같은 잡음을 구분할 수 있습니다.
참고 링크
2 sources