Search Unity

최근 진행된 Unite Now 세션에서 버스트 컴파일러를 이용하여 ARM Neon 명령어 집합을 활용할 수 있는 방법에 대해 소개했습니다. Android 기기를 대상으로 개발 중이라면 버스트 컴파일러로 ARM 아키텍처의 지원을 받아 Unity 프로젝트의 성능을 향상할 수 있습니다.

Unity와 ARM은 Android 생태계에 속한 수십억 대의 ARM 기반 모바일 기기를 대상으로 하는 모바일 게임 개발 경험을 강화하기 위해 파트너십을 맺었습니다.

게임 개발에서 성능은 절대적인 요소입니다. ARM은 더 우수한 환경을 구축하는 데 필요한 성능과 효율성을 향상하고자 CPU와 GPU 기술에 지속적으로 투자하고 있습니다. 최근 ARM은 전원 효율성이 크게 향상된 Cortex-A78과 그보다 훨씬 더 인상적인 성능을 자랑하는 Cortex-X1이라는 두 가지 신제품을 발표했습니다. 이러한 하드웨어의 개발은 ARM 아키텍처에 적합한 컴파일러 기술의 발전을 통해 뒷받침됩니다. 컴파일러를 이용하면 고성능 게임을 개발한 후 ARM 아키텍처의 특징을 가장 효과적으로 활용하는 효율적인 바이너리로 변환 및 최적화할 수 있습니다.

버스트 소개

버스트는 첨단 컴파일러 기술로서, 새로운 데이터 지향 기술 스택(DOTS)과 Unity 잡 시스템으로 만든 Unity 프로젝트의 성능을 가속화합니다. 버스트는 고성능 C#(HPC#)이라고 불리는 C# 언어의 하위 집합을 컴파일하고 LLVM 컴파일러 프레임워크를 바탕으로 하는 고급 최적화를 사용하여 기기의 성능을 효율적으로 활용합니다.

버스트는 애플리케이션에 숨겨진 병렬성을 활용하기에 적합한 컴파일러입니다. DOTS 프로젝트에서는 버스트를 손쉽게 사용할 수 있으며 CPU 바운드 알고리즘의 성능을 크게 향상할 수 있습니다. 아래의 동영상에서 버스트가 활성화된 데모 환경과 활성화되지 않은 데모 환경의 스크립트 실행을 나란히 비교해 볼 수 있습니다.

이 데모에서는 Unity Physics를 이용한 시뮬레이션의 예시를 3개 보여줍니다. 버스트로 컴파일링된 코드는 물리 요소가 더 많은 프레임을 더 빠르게 연산할 수 있으므로 성능은 향상되고 서멀 스로틀링과 배터리 소모량은 감소하면서 콘텐츠의 몰입도는 더욱 높아집니다.

버스트의 작동 방식

버스트는 어떤 방식으로 작동할까요?

버스트는 HPC# 코드를 LLVM 컴파일러에서 사용되는 중간 언어인 LLVM IR로 변환합니다. 따라서 컴파일러에서 LLVM의 코드 생성 지원을 최대한 활용하고 ARM 아키텍처에서 프로그램의 데이터 흐름에 맞춰 최적화된 효율적인 기계어 코드를 생성할 수 있게 됩니다. 아래의 다이어그램에 과정이 설명되어 있습니다

마이크 액튼은 “데이터 지향 디자인과 C++”라는 강연에서 성능을 극대화하기 위해 “하드웨어와 데이터를 알아야 한다”고 강조했습니다. 버스트는 HPC# 언어와 DOTS 프레임워크가 배열 앨리어싱의 제한에 대한 가시성을 제공하여 효과적으로 작동하며, 하드웨어 아키텍처에 대한 LLVM의 지식도 활용할 수 있습니다. 따라서 버스트 컴파일러를 사용하면 Unity API를 기반으로 작성된 스크립트의 속성에 맞게 대상에 적합한 변환을 수행할 수 있습니다.

버스트 사용하기

버스트를 이용하여 DOTS에서 잡 시스템을 활용하는 C# 스크립트를 컴파일할 수 있습니다. 다음과 같이 [BurstCompile] 속성을 잡 정의에 추가하면 됩니다.

Jobs 메뉴에 있는 Burst Inspector를 사용하면 생성될 코드를 확인할 수 있습니다. 이 데모에서는 Safety Checks를 비활성화했으며 Burst 1.3.3버전을 사용하고 있습니다.

Burst Inspector에서 ARMV8A_AARCH64 타겟을 선택하여 Armv8-A에 맞는 코드를 생성할 수 있습니다.

이제 Neon 명령어 집합을 사용하는 코어 루프 등 C# 루프에 맞게 생성된 AArch64 코드를 확인할 수 있습니다.

버스트 컴파일러 사용에 관한 자세한 내용은 명령어 매뉴얼을 참조하세요. Unite Now에서 위 단계를 더 자세하게 살펴볼 수 있으며, 포럼을 방문하여 버스트 사용 방법을 살펴보고 피드백을 공유해 주세요.

24 replies on “버스트 컴파일러로 모바일 성능 강화”

We had a more than 10x performance boost in CPU heavy parts of a mobile game and the effort was just less than a week to convert all related code to use burst and unmanaged memory in a proper manner.

In our case access to raw textures and meshes helped a lot as well.

I wanted to do that right after the video went public, but it slipped through cracks somehow. Let me see what I can do.

Now that Unity Learn is free, I would love to see more stuff on Burst. Thanks!
Also there is a typo, “Mike Action” > “Mike Acton”

What point is there to Burst coupled with ECS if systems’ main thread work and job scheduling exceeds the execution time of Burst jobs most of the time?

Hey there Nikolai. Thanks for reaching out! Wanted to pass along from the team that they are aware of this overhead, and are actively working on reducing it.

As Trey said, job scheduling optimization are on their way. The goal of the team working on it is to ensure that the overhead of scheduling a job is minimal (thus greatly improving the throughput). We’ll keep you posted!

We have to think about the future too. Your current projects will probably just stick to current tech, but future projects can be made with DOTS from the get go.

If we only want solutions that remain 100% compatible with the old monobehaviour flow, we’ll never see anything that brings huge improvements. Not even the best engineers in the world could make all that performance happen without requiring rewrites

I guess “for free” means “without using more memory”, which is a common trade-off for many optimizations like pooling, caching, baking etc.

Bit sensitive over an optimisation article? No need to call someone a liar. Frank is right, that it means ‘for free’ without any trade-offs and is welcome.

If you are creating a new game with ECS, then you don’t have to rewrite anything. It is true that you can’t take your existing game, add [BurstCompile] and enjoy performance improvements – I’ve also covered that in the slide explaining the limitations. However, as people have answered, there is no memory overhead or other kind of impact, so it’s _almost_ for free.

Would be interesting to see a comparison between “regular PhysX”, “Havok Physics” and “Unity Physics”.

The one shown here feels very flawed, comparing “Unity Physics, optimized for Burst but not using Burst” with “Unity Physics as it was designed”… This does not show the power of Burst at all.

(I think Burst is great, but your example doesn’t make sense)

Thank you for the kind words.
I would rather say Unity.Physics is designed for ECS (pure C#, stateless) and not exactly optimized for Burst – there is still room for optimizations, especially with the hardware intrinsics in Burst. We’ll be working on that.

Comments are closed.