Unity Burst AOT Settings의 의미와 도입 판단
Burst는 Unity의 컴파일러로, .NET IL을 LLVM으로 대상 CPU에 맞춘 네이티브 코드로 바꾼다. 대상은 [BurstCompile]을 붙인 Job과 정적 메서드(함수 포인터 포함)이고, C#의 일부인 HPC#(High-Performance C#)만 컴파일한다(Burst 매뉴얼).
AOT(Ahead-Of-Time)는 실행 중에 컴파일하지 않고 빌드 시점에 플랫폼별 기계어로 미리 컴파일해 두는 방식이다. Player 빌드에서 Burst는 이 방식으로 코드를 포함시킨다.
Burst AOT Settings 항목
섹션 제목: “Burst AOT Settings 항목”위치는 Edit > Project Settings > Burst AOT Settings이고, Player 빌드에만 적용된다. 플랫폼마다 따로 설정한다. Editor에서의 컴파일은 Jobs > Burst 메뉴에서 정한다(Burst AOT Settings reference).
| 항목 | 의미 |
|---|---|
| Enable Burst Compilation | 선택한 플랫폼에서 Burst 컴파일을 켜거나 끈다. 끄면 Burst 대상 코드도 일반 C# 경로(Mono/IL2CPP)로 실행된다. |
| Enable Optimizations | Burst 최적화를 켠다. 컴파일러 문제를 의심할 때 끄고 비교한다. |
| Force Debug Information | 릴리스 빌드에서도 디버그 심볼을 생성한다. 빌드된 게임의 크래시 위치를 추적할 때 쓴다. |
| Use Platform SDK Linker | 크로스 컴파일 지원을 끄고 플랫폼 SDK 도구로 링크한다. 디버깅 목적으로만 켠다. |
| Target 32Bit / 64Bit CPU Architectures | x86/x64 빌드에 넣을 명령어 집합을 고른다. 기본값은 SSE2와 SSE4다. |
| Target Arm 64Bit CPU Architectures | Arm64 빌드의 대상 아키텍처를 고른다. 기본값은 ARMV8A다. |
| Optimize For | Performance, Size, Fast Compilation, Balanced 중에서 고른다. 기본값은 Balanced다. Fast Compilation은 벡터화·인라이닝·루프 최적화를 하지 않는다. |
| Floating Point Mode | Burst 코드의 기본 부동소수점 모드다. BurstCompile의 FloatMode로 개별 지정할 수 있다. |
| Disabled Warnings | Player 빌드에서 끌 Burst 경고 번호 목록(세미콜론 구분)이다. 모든 플랫폼에 공통이다. |
| Stack Protector | 스택 보호 수준(Off, Basic, Strong, All)을 정한다. |
CPU 아키텍처 설정은 Windows, macOS, Linux, Android에만 적용된다. 여러 개를 고르면 Burst가 실행 시점에 CPU에 맞는 코드를 고르는 디스패치를 넣는다.
x64 명령어 집합
섹션 제목: “x64 명령어 집합”SIMD(한 명령어로 여러 데이터를 처리) 확장 단계에 따라 나뉜다.
- SSE2: 64비트 x86 CPU의 기본 명령어 집합이다. 호환성을 위한 최소 경로로 둔다.
- SSE4: SSE2보다 명령어가 늘어난 버전이다. 2008년 이후 CPU 대부분이 지원한다.
- AVX: 부동소수점 벡터 레지스터를 128비트에서 256비트로 넓혔다. 2011년 Sandy Bridge부터 지원한다.
- AVX2: 정수 연산까지 256비트로 확장했다. 2013년 Haswell부터 지원한다.
128비트 레지스터는 float 4개, 256비트는 8개를 한 번에 담는다. SSE2와 AVX2를 함께 고르면 빌드에 두 경로가 모두 들어가고, 실행 시점에 사용자 CPU를 검사해 맞는 경로를 쓴다.
빌드 종류별 설정
섹션 제목: “빌드 종류별 설정”| 항목 | 개발 빌드 | 배포 빌드 |
|---|---|---|
| Enable Optimizations | 빌드 속도가 중요하면 Off | On |
| Force Debug Information | On (크래시 추적) | Off (용량 절약) |
| 64Bit CPU Architectures | SSE2 (빌드 시간 절약) | SSE2 + AVX2 (호환성과 성능) |
배포 빌드에서도 크래시 스택을 네이티브 수준까지 봐야 하면 Force Debug Information을 켠다. 빌드 시간을 줄이려면 Optimize For를 Fast Compilation으로 두는 방법도 있지만 벡터화가 빠진다.
옵션만 켠다고 기존 코드가 빨라지지 않는다
섹션 제목: “옵션만 켠다고 기존 코드가 빨라지지 않는다”Enable Burst Compilation은 [BurstCompile]이 붙은 Job과 함수에만 영향을 준다. 일반 C# 코드는 그대로 Mono/IL2CPP로 실행된다. HPC#은 관리 객체를 다루는 메서드를 지원하지 않으므로(HPC# overview), class, List<T>, Dictionary 기반 로직은 Burst로 옮기려면 다시 작성해야 한다.
일반 C# 코드
섹션 제목: “일반 C# 코드”using UnityEngine;using System.Collections.Generic;
public class StandardExample : MonoBehaviour{ List<float> numbers = new List<float>();
void Start() { for (int i = 0; i < 100000; i++) numbers.Add(i); }
void Update() { for (int i = 0; i < numbers.Count; i++) { // Burst 대상이 아니므로 Mono/IL2CPP 코드로 실행된다. numbers[i] = numbers[i] * numbers[i]; } }}Burst 옵션을 켜도 이 코드의 실행 경로는 바뀌지 않는다.
Burst + Job System 코드
섹션 제목: “Burst + Job System 코드”using UnityEngine;using Unity.Burst;using Unity.Collections;using Unity.Jobs;
public class BurstExample : MonoBehaviour{ NativeArray<float> numbers;
void Start() { numbers = new NativeArray<float>(100000, Allocator.Persistent); }
void Update() { var job = new SquareJob { Data = numbers };
// 배열 길이와 배치 크기를 넘겨 여러 워커 스레드에 나눠 실행한다. JobHandle handle = job.Schedule(numbers.Length, 64); handle.Complete(); }
void OnDestroy() { if (numbers.IsCreated) numbers.Dispose(); }}
[BurstCompile]public struct SquareJob : IJobParallelFor{ public NativeArray<float> Data;
public void Execute(int index) { // Burst가 네이티브 코드로 컴파일하고, 가능하면 벡터화한다. Data[index] = Data[index] * Data[index]; }}| 구분 | 일반 C# 코드 | Burst + Job 코드 |
|---|---|---|
| 데이터 저장 | List<T>, class |
NativeArray<T>, struct |
| 속성 | 없음 | [BurstCompile] 필요 |
| 구조 | MonoBehaviour.Update() 안의 루프 |
IJobParallelFor 등을 구현한 구조체 |
| Burst 옵션의 영향 | 없음 | Burst로 컴파일됨 |
도입 판단
섹션 제목: “도입 판단”- CPU 부하가 큰 로직을 Job과 Burst로 옮기면 SIMD 벡터화와 멀티코어 분산을 함께 얻는다.
- HPC# 코드는 관리 객체를 쓰지 않으므로 해당 구간에서 GC 할당이 생기지 않는다.
class를struct로,List<T>를NativeArray<T>같은 네이티브 컨테이너로 바꾸는 리팩토링이 필요하다. 네이티브 메모리는 직접 해제해야 한다.- HPC#은
catch를 지원하지 않고, Player 빌드에서 던진 예외는 항상 앱을 종료시킨다. - Burst 컴파일 단계가 추가돼 빌드 시간이 늘 수 있다.
- 네이티브 코드라 일반 C#보다 디버깅과 에러 추적이 어렵다.
균형점
섹션 제목: “균형점”Job System을 쓰지 않는 프로젝트에서는 옵션을 켜도 얻는 것이 없다. 프로파일링으로 확인한 CPU 병목이 없으면 도입 실익이 낮다. 물리 계산, 대량 AI, 많은 투사체 이동처럼 연산량이 큰 구간이 병목으로 확인되면, 그 모듈만 골라 Job과 Burst로 옮기는 부분 도입이 리팩토링 비용을 줄인다.