# Burst compiler Compile compatible sections of your C# code into highly-optimized native CPU code. Burst is a compiler that works on a subset of C# referred to in the Unity context as High-Performance C# (HPC#). Burst uses LLVM to translate .NET Intermediate Language (IL) to code that's optimized for performance on the target CPU architecture. Burst was originally designed for use with Unity's job system. Jobs are structs that implement the IJob interface and represent small units of work that can run in parallel to make best use of all available CPU cores. Designing or refactoring your project to split work into Burst-compiled jobs can significantly improve the performance of CPU-bound code. Aside from jobs, Burst can also compile static methods, as long as the code inside them belongs to the supported subset of C#. Mark code for Burst compilation by applying the `[BurstCompile]` attribute to jobs or to static methods and their parent type. | Topic | Description | | --------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- | | Get started | Get started with Burst by creating your first simple Burst-compiled example code. | | C# language support | Check which elements of the C# language belong to the high-performance subset of C# that Burst can compile. | | Burst compilation | Understand how Burst compiles code in different contexts, mark your code for Burst compilation, and configure aspects of the compilation process. | | Burst intrinsics | Use low-level intrinsics to get extra performance from Burst if you're writing single instruction, multiple data (SIMD) assembly code. | | Editor reference | Use the Burst menu and Burst Inspector window in the Unity Editor to configure Burst options and inspect the Burst-compilable jobs in your project. | | Building your project | Build your project with the appropriate toolchains and Burst Ahead-of-Time (AOT) compilation settings for your target platform and architecture. | | Optimization | Debug and profile to identify bugs or bottlenecks in Burst-compiled code and configure a range of options to optimize performance. | | Modding support | Include Burst-compiled code as additional libraries in your mods. | ### Installation To install the Burst package, follow the instructions in the Add and remove UPM packages or feature sets documentation. If you change the Burst package version (for example, via Update), you need to close and restart the Editor. ### Additional resources #### Videos Conference presentations given by the Burst team: * Getting started with Burst - Unite Copenhagen 2019 * Supercharging mobile performance with ARM Neon and Unity Burst Compiler * Using Burst Compiler to optimize for Android - Unite Now 2020 * Intrinsics: Low-level engine development with Burst - Unite Copenhagen 2019 (slides) * Behind the Burst compiler: Converting .NET IL to highly optimized native code - DotNext 2018 * Deep dive into the Burst compiler - Unite LA 2018 * C# to machine code: GDC 2018 * Using the native debugger for Burst compiled code #### Blogs Blog posts written by members of the Burst team : * Raising your game with Burst 1.7 * Enhancing mobile performance with the Burst compiler * Enhanced aliasing with Burst * In parameters in Burst --- # Get started You can use Burst to compile jobs or static methods in non-job C# types. To start using the Burst compiler in your code, decorate a job or static method with the `[BurstCompile]` attribute. For more information on where and when to apply the `[BurstCompile]` attribute, refer to Marking code for Burst compilation. ### Compiling jobs with Burst For jobs, you only need to apply the `[BurstCompile]` attribute to the job declaration and Burst compiles everything inside the job automatically. The following example demonstrates this: ``` csharp using Unity.Burst; using Unity.Collections; using Unity.Jobs; using UnityEngine; public class MyBurst2Behavior : MonoBehaviour { void Start() { var input = new NativeArray<float>(10, Allocator.Persistent); var output = new NativeArray<float>(1, Allocator.Persistent); for (int i = 0; i < input.Length; i++) input[i] = 1.0f * i; var job = new MyJob { Input = input, Output = output }; job.Schedule().Complete(); Debug.Log("The result of the sum is: " + output[0]); input.Dispose(); output.Dispose(); } // Using BurstCompile to compile a Job with Burst [BurstCompile] private struct MyJob : IJob { [ReadOnly] public NativeArray<float> Input; [WriteOnly] public NativeArray<float> Output; public void Execute() { float result = 0.0f; for (int i = 0; i < Input.Length; i++) { result += Input[i]; } Output[0] = result; } } } ``` ### Compiling static methods with Burst For static methods, you must apply the `[BurstCompile]` attribute to both the individual methods you want Burst to compile and to the declaration of the parent type. The following example demonstrates this: ``` csharp using Unity.Burst; using Unity.Collections; using Unity.Jobs; using UnityEngine; [BurstCompile] public static class MyBurstUtilityClass { [BurstCompile] public static void BurstCompiled_MultiplyAdd(in float4 mula, in float4 mulb, in float4 add, out float4 result) { result = mula * mulb + add; } } ``` For more information on how you can call this Burst-compiled utility class and its member method from your C# code, refer to Calling Burst-compiled code. ### Compiling static methods with Burst For static methods, you must apply the `[BurstCompile]` attribute to both the individual methods you want Burst to compile and to the declaration of the parent type. The following example demonstrates this: ``` csharp using Unity.Burst; using Unity.Collections; using Unity.Jobs; using UnityEngine; [BurstCompile] public static class MyBurstUtilityClass { [BurstCompile] public static void BurstCompiled_MultiplyAdd(in float4 mula, in float4 mulb, in float4 add, out float4 result) { result = mula * mulb + add; } } ``` For more information on how you can call this Burst-compiled utility class and its member method from your C# code, refer to Calling Burst-compiled code. ### Limitations Burst supports most C# expressions and statements, with a few exceptions. For more information, refer to C# language support. ### Compilation Burst compiles your code just-in-time (JIT) while in Play mode in the Editor, and ahead-of-time (AOT) when your application runs in a Player. For more information on compilation, refer to Burst compilation ### Command line options You can pass the following options to the Unity Editor on the command line to control Burst: --burst-disable-compilation disables Burst. --burst-force-sync-compilation force Burst to compile synchronously. For more information, refer to Burst compilation. ### Additional resources Burst compilation `[BurstCompile]` attribute --- # C# language support ## HPC# overview Burst uses a high performance subset of C# called High Performance C# (HPC#). ## Supported C# features in HPC# HPC# supports most expressions and statements in C#. It supports the following: | Supported feature | Notes | | ----------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Extension methods. | | | Instance methods of structs. | | | Unsafe code and pointer manipulation. | | | Loading from static read-only fields. | For more information, see the documentation on Static read-only fields and static constructors. | | Regular C# control flows. | if <br>else <br>switch <br>case <br>for <br>while <br>break <br>continue | | ref and out parameters | | | fixed statements | | | Some IL opcodes. | cpblk <br>initblk <br>sizeof | | DLLImport and internal calls. | For more information, see the documentation on DLLImport and internal calls. | | try and finally keywords. Burst also supports the associated IDisposable patterns, using and foreach. | If an exception happens in Burst, the behavior is different from .NET. In .NET, if an exception occurs inside a try block, control flow goes to the finally block. However, in Burst, if an exception happens inside or outside a try block, the exception throws as if any finally blocks do not exist. Invoking foreach calls is supported by Burst, but there is a foreach edge case that burst currently does not support (see "Foreach and While" section for more details). | | Strings and ProfilerMarker. | For more information, see the documentation on Support for Unity Profiler markers. | | throw expressions. | Burst only supports simple throw patterns, for example, throw new ArgumentException("Invalid argument"). When you use simple patterns like this, Burst extracts the static string exception message and includes it in the generated code. | | Strings and Debug.Log. | Only partially supported. For more information, see the documentation on String support and Debug.Log. | Burst also provides alternatives for some C# constructions not directly accessible to HPC#: * Function pointers as an alternative to using delegates within HPC# * Shared static to access static mutable data from both C# and HPC# ### Exception expressions Burst supports throw expressions for exceptions. Exceptions thrown in the Editor can be caught by managed code, and are reported in the console window. Exceptions thrown in Player builds always cause the application to abort. Thus with Burst you should only use exceptions for exceptional behavior. To ensure that code doesn't end up relying on exceptions for things like general control flow, Burst produces the following warning on code that tries to throw within a method not attributed with `[Conditional("ENABLE_UNITY_COLLECTIONS_CHECKS")]`: > Burst warning BC1370: An exception was thrown from a function without the correct `[Conditional("ENABLE_UNITY_COLLECTIONS_CHECKS")]` guard. Exceptions only work in the editor and so should be protected by this guard ### Foreach and While Burst supports invoking foreach and while. However, there is an edge case which is currently unsupported - methods that take one or more generic collection parameters `T: IEnumerable<U>` and invoke foreach or while on at least one of the collections in the method body. To illustrate, the following example methods exemplify this limitation: ``` csharp public static void IterateThroughConcreteCollection(NativeArray<int> list) { foreach (var element in list) { // This works } } public static void IterateThroughGenericCollection<S>(S list) where S : struct, IEnumerable<int> { foreach (var element in list) { // This doesn't work } } ``` Note that the uppermost method `IterateThroughConcreteCollection()`'s parameter is specified to be a concrete collection type, in this case `NativeArray<int>`. Because it's concrete iterating through it inside the method will compile in Burst. In the method `IterateThroughGenericCollection()` below it, however, the parameter is specified to be a generic collection type `S`. Iterating through `S` inside the method will therefore not compile in Burst. It will instead throw the following error: >Can't call the method (method name) on the generic interface object type (object name). This may be because you are trying to do a foreach over a generic collection of type IEnumerable. ### Unsupported C# features in HPC# HPC# doesn't support the following C# features: * Catching exceptions catch in a try/catch. * Storing to static fields except via Shared Static. * Any methods related to managed objects, for example, string methods. ### Additional resources * Static read-only fields and static constructor support * String support * C#/.NET type support * C#/.NET System namespace support ## Static read-only fields and static constructor support Burst evaluates all static fields and all static constructors at compile time. It evaluates all the static fields and the static constructors for a given struct together. Burst only supports read-only static fields. A static field that isn't read-only in a Burst-compiled struct causes a compilation error. When Burst fails to evaluate any static field or static constructor, all fields and constructors fail for that struct. When compile-time evaluation fails, Burst falls back to compiling all static initialization code into an initialization function that it calls once at runtime. This means that your code needs to be Burst compatible, or it will fail compilation if it fails compile-time evaluation. An exception to this is that there's limited support for initializing static read-only array fields as long as they're initialized from either an array constructor or from static data: - `static readonly int[] MyArray0 = { 1, 2, 3, .. };` - `static readonly int[] MyArray1 = new int[10];` ## Language support Burst doesn't support calling external functions and function pointers. It supports using the following base language with static read-only fields and constructors: - Managed arrays - Strings - Limited intrinsic support: - `Unity.Burst.BurstCompiler.IsEnabled` - `Unity.Burst.BurstRuntime.GetHashCode32` - `Unity.Burst.BurstRuntime.GetHashCode64` - Vector type construction - Limited intrinsic assertion support: - `UnityEngine.Debug.Assert` - `NUnit.Framework.Assert.AreEqual` - `NUnit.Framework.Assert.AreNotEqual` - Simple throw patterns. Any exceptions thrown during evaluation become compiler errors. ### Additional resources * String support * C#/.NET type support * C#/.NET System namespace support ## String support ## Calling Burst-compiled code ## Function pointers ## C#/.NET type support ## C#/.NET System namespace support ## DllImport and internal calls ## SharedStatic struct --- # Burst compilation ## Marking code for Burst compilation ## Excluding code from Burst compilation ## Defining Burst options for an assembly ## Burst compilation in Play mode ## Generic jobs ## Compilation warnings reference --- # Burst intrinsics ## Burst intrinsics Common class ## Processor specific SIMD extensions ### Arm Neon intrinsics reference --- # Editor reference ## Burst menu reference ## Burst Inspector window reference --- # Building your project ## Burst AOT Settings reference --- # Optimization ## Debugging and profiling tools ## Loop vectorization ## Memory aliasing ### NoAlias attribute ### Aliasing and the job system ## AssumeRange attribute ## Hint intrinsic ## Constant intrinsic ## SkipLocalsInit attribute --- # Modding support