Search Unity

Enhancing mobile performance with the Burst compiler

August 17, 2020 in Engine & platform | 3 min. read
Topics covered
Share

Is this article helpful for you?

Thank you for your feedback!

As part of a recent session at Unite Now, we discussed how technology in the Burst compiler enables developers who are building projects with Unity to take advantage of the Arm Neon instruction set. You can use the Burst compiler when targeting Android devices to improve the performance of Unity projects supported by Arm architecture.

Unity and Arm have formed a partnership to enhance the mobile game development experience for the billion-plus Arm-powered mobile devices in the Android ecosystem. 

For game developers, performance is paramount. Year after year, Arm invests in improving its CPU and GPU technologies to provide the advances in performance and efficiency needed to build richer experiences. Recently, Arm announced two new products, Cortex-A78, which provides greatly improved power efficiency, and the even more impressive Cortex-X1. These hardware developments are complemented by advances in compiler technology for the Arm architecture. Compilers ensure that when you develop high-performance games, they are translated and optimized into efficient binaries that make the best use of the Arm architecture’s features.

About Burst

Burst is an ahead of time compiler technology that can be used to accelerate the performance of Unity projects made using the new Data-Oriented Technology Stack (DOTS) and the Unity Job System. Burst works by compiling a subset of the C# language, known as High-Performance C# (HPC#), to make efficient use of a device’s power by deploying advanced optimizations built on top of the LLVM compiler framework. 

Burst is great for exploiting hidden parallelism in your applications. Using Burst from a DOTS project is easy, and it can unlock big performance benefits in CPU-bound algorithms. In this video, you can see a side-by-side comparison of a scripted run through in a demo environment with and without Burst enabled.

This content is hosted by a third party provider that does not allow video views without acceptance of Targeting Cookies. Please set your cookie preferences for Targeting Cookies to yes if you wish to view videos from these providers.

The demo shows three examples of simulations using Unity Physics. You will see that the Burst-compiled code is able to compute frames with higher numbers of physics elements faster, allowing for better performance, less thermal throttling, lower battery consumption, and more engaging content.

How does Burst work?

We say that Burst brings performance for free, but how does that work?

Burst transforms HPC# code into LLVM IR, an intermediate language used by the LLVM compiler framework. This allows the compiler to take full advantage of LLVM’s support for code generation for the Arm architecture to generate efficient machine code optimized around the data flow of your program. A diagram of this flow is shown below.

graph

Mike Acton has given a talk called “Data-oriented design and C++,” which features the key line “know your hardware, know your data” as a means of achieving maximum performance. Burst works well because it gives visibility to the constraints on array aliasing that are guaranteed by the HPC# language and the DOTS framework, and it can make use of LLVM’s knowledge of your hardware architecture. This enables Burst to make target-specific transformations based on the properties of scripts written against the Unity APIs.

How to program for Burst

You can use Burst to compile C# scripts that make use of the Unity Jobs System in DOTS. This is done by adding the [BurstCompile] attribute to your Job definition: 

[BurstCompile]
struct MyJob : IJob
{
  public NativeArray<float> Input;
  public NativeArray<float> Output;
  public void Execute()
  {
	for (int I = 0; I < Input.Length; i++)
	{
  	Output[i] = Input[i] * Input[i];
	}
  }
}

We can use the Burst Inspector, found in the Jobs menu, to see what code will be generated. Note that for this demonstration, we have disabled Safety Checks and are using Burst 1.3.3.

Window

In the Burst Inspector that appears, we enable code generation for Armv8-A by selecting the ARMV8A_AARCH64 target.

Burst inspector

We can now see the AArch64 code that will be generated for our C# loop, including a core loop using the Neon instruction set.

code

For more details on using the Burst compiler, please see the instruction manual, check out this Unite Now talk, where we go through the steps above in more detail, or head to the forums to get more information or ask questions about using Burst in your next project.

August 17, 2020 in Engine & platform | 3 min. read

Is this article helpful for you?

Thank you for your feedback!

Topics covered