Search Unity

Optimize your projects with Burst Compiler 1.3

May 27, 2020 in Technology | 6 min. read
Topics covered
Share

Is this article helpful for you?

Thank you for your feedback!

Since the first stable release of Burst Compiler a year ago, we have been working to improve the quality, experience, and robustness of the compiler. As we’ve released a major new version, Burst 1.3, we would like to take this opportunity to give you more insights about why we are excited about it and what’s coming next.

We’re trying to constantly listen to our users and Unity partners. Also, internal teams at Unity are using Burst more and more. Based on this feedback, we have been prioritizing our work for the past quarter to ensure that we’re always thoroughly balancing the following 4 areas of improvements:

  • Scalability
  • Performance
  • Quality
  • Usability and Debuggability

As Burst is a core part of DOTS (Data-Oriented Technology Stack), the new 1.3 release of the Burst Compiler is trying to improve each of these areas to improve user experience.

Cross compilation for Desktop

Many of you have requested an option to compile a desktop player for a platform different from where the editor is running. One typical scenario is when you use Unity Build Cloud Services and the build machines are running on macOS while you’re trying to generate players for Windows. This new version of Burst enables the compilation of a Mono-based player across different desktop platforms.

Note that this new feature applies only for desktop build players. Console and mobile platforms usually have restrictions about which platform they can be compiled from as their SDK is often compatible with only one host platform.

Native Debugging

Debugging code compiled with Burst is another much-awaited usability feature. Until recently, the only way to debug Burst code was to actually disable Burst and rely on existing .NET managed debugging facilities. 

With Burst 1.3, you can now use any integrated IDE native debugger found in Visual Studio, XCode or VSCode and debug Burst code with it:

In order to enable this feature, you need to select Enable Native Debugging in the Unity Editor Burst menu. The debugging experience allows you to:

  • Hit breakpoints, including conditional breakpoints (data breakpoints should work too)
  • Inspect frame callstack
  • Inspect local variables
  • Inspect structures and data, follow pointers
  • Use debugger watches

You need a separate native debugger launched from your regular .NET IDE in order to use this feature. You can then attach this native debugger to your game or even the Unity Editor. You can watch the following video tutorial for more details.

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.

We understand that a more integrated debugging experience alongside regular .NET managed code is something that our users are looking forward to. This is something that we want to pursue as well, even though it’s difficult to bring about without penalizing the debugging experience. But we will try to improve this situation in the future.

Debug.Log and strings support

Another usability feature is the support for Debug.Log and partial string support available for Unity 2019.3 and above.

int value = 256;

Debug.Log($"This is an integer value {value} logged with Burst.");

You can learn more about this feature from this documentation.

New Intel CPU Intrinsics API

Burst has been optimized to leverage the power of SIMD. The Unity Mathematics package supported by Burst provides an API to manipulate standard vector types (e.g float3, float4) and to perform various calculations encountered by 2D and 3D workloads more efficiently. 

We also understand that in order to fully take advantage of existing hardware and to empower our users, we need not only to provide this abstract math API, but also to unlock more advanced optimization scenarios. With this new release, we’re introducing a new Intel CPU Intrinsics API to cover that performance aspect.

v128 a = Input.ReinterpretLoad<v128>(i);

v128 mask = cmplt_ps(a, Limit);

int m = movemask_ps(a);

v128 packed = shuffle_epi8(a, Lut[m]);

Output.ReinterpretStore(outputIndex, packed);

outputIndex += popcnt_u32((uint)m);

Compilation Time

As more and more studios and teams are using it to optimize their games, Burst has to compile and optimize an increasing amount of user code. In the previous version, we introduced multithreaded compilation for both in-Editor experience and when building a standalone player, but the compiler still had to recompile your entire project whenever you restarted the editor.

We’re working on improving this scalability problem by first introducing in Burst 1.3 the caching of compilation results to disk, so that whenever you restart the editor, Burst should no longer try to recompile code that was previously compiled.

But we’re not where we want to be with compilation times just yet. In the next quarter, we’re actively working to improve further and help larger projects iterate faster with Burst.

Better codegen

Thanks to the C# Job System which ensures that concurrent write accesses are impossible, the Burst Compiler is in a unique position to better optimize your code than a regular C++ compiler. One of the critical optimizations that Burst allows is auto-vectorization, which can bring a 3x to 4x performance boost over regular scalar code. When you couple this with a carefully crafted layout of your game data, you can get improve the efficiency of your code by another order of magnitude, compared to non-data-oriented game code.

In this new version of Burst, we have rewritten the memory aliasing analysis which is the entry point to actually auto-vectorize your code. We’re also introducing new intrinsics,  providing asserts to your code that can verify that two memory references aren’t aliasing or that a loop should vectorize (this one is still experimental).

You can learn more about this unique feature from this Memory Aliasing and noalias documentation.

More bug fixes

The Burst Compiler should generate code that you can safely rely on, but as with any other compiler, it can have bugs. Since the 1.2 release, we have fixed many issues and invalid codegen cases. But we’re also trying to make sure that the quality of the compiler is rock solid by adding more and more unit tests and integration tests with larger projects for every new release.

While it improves codegen performance, this new release should also be safer to use in your projects.

What’s next?

We’re constantly adapting our priorities based on your feedback. In the coming months, we’ll be working on:

  • Improving compilation time for both editor experience and player builds.
  • Improving codegen.
  • Bringing a new intrinsics API for Arm CPUs.
  • Various improvements in C# support (foreach, IDisposable…)

Start using Burst

Burst is part of DOTS and you can already use it now! It’s stable and we’re actively working on improving it.

It supports major desktop, console, and mobile platforms. It’s verified for Unity 2018.4 and newer, including the latest Unity 2020.2 alpha.

We will come back in an upcoming series of blog posts to provide better guidance on using Burst as well as insights about what’s coming next.

In the meantime, let us know what you are doing with it and if you have any questions or issues, please feel free to leave a message on the DOTS forum!

May 27, 2020 in Technology | 6 min. read

Is this article helpful for you?

Thank you for your feedback!

Topics covered