# Quick Start # Compile a Job with the Burst compiler Burst is primarily designed to work efficiently with the Job system. You can start using the Burst compiler in your code by simply decorating a Job struct with the attribute `[BurstCompile]` ```c# using Unity.Burst; using Unity.Collections; using Unity.Jobs; using UnityEngine; public class MyBurst2Behavior : MonoBehaviour { void Start() { var input = new NativeArray(10, Allocator.Persistent); var output = new NativeArray(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 // Set CompileSynchronously to true to make sure that the method will not be compiled asynchronously // but on the first schedule [BurstCompile(CompileSynchronously = true)] private struct MyJob : IJob { [ReadOnly] public NativeArray Input; [WriteOnly] public NativeArray Output; public void Execute() { float result = 0.0f; for (int i = 0; i < Input.Length; i++) { result += Input[i]; } Output[0] = result; } } } ``` By default (only within the Editor - See [AOT vs JIT](#just-in-time-jit-vs-ahead-of-time-aot-compilation)), Burst JIT compiles jobs asynchronously, but the example above uses the option `CompileSynchronously = true` to make sure that the method is compiled on the first schedule. In general, you should use asynchronous compilation. See [`[BurstCompile]` options](AdvancedUsages.md#synchronous-compilation) # Jobs/Burst Menu The Burst package adds a few menu entries to the Jobs menu for controlling Burst behavior: ![Burst menu entries](../images/burst-menu.png) - **Enable Compilation**: When checked, Burst compiles Jobs and Burst custom delegates that are tagged with the attribute `[BurstCompile]`. Default is checked. - **Enable Safety Checks**: Has three options in a sub-menu: - **Off** - disable safety checks across all Burst jobs/function-pointers. This is a dangerous setting that should only be used when you want more realistic profiling results from in-editor captures. A reload of the Unity Editor will always reset this to On. - **On** - Burst enables safety checks on code that uses collection containers (e.g `NativeArray`). Checks include job data dependency and container indexes out of bounds. This is the default. - **Force On** - Force safety checks on _even for jobs/function-pointers that have_ `DisableSafetyChecks = true`. Prior to reporting any Burst bug this option should be set to rule out any problems that safety checks could have caught. - **Synchronous Compilation**: When checked, Burst will compile synchronously - See [`[BurstCompile]` options](AdvancedUsages.md#synchronous-compilation). Default is unchecked. - **Native Debug Mode Compilation**: When checked, Burst will disable optimizations on all code compiled, in order to make it easier to debug via a native debugger - See [Native Debugging](DebuggingAndProfiling.md#native-debugging). Default is unchecked. - **Show Timings**: When checked, Burst logs the time it takes to JIT compile a Job in the Editor. Default is unchecked. - **Open Inspector...**: Opens the [Burst Inspector Window](#burst-inspector). The **Show Timings** option will result in a log being output on the Unity Editor Console for each _library_ of entry-points we compile. Remember - Burst batches the compilation into units of methods-per-assembly, and so multiple entry-points will be grouped together in a single compilation task. Broadly this output is _mostly_ useful when reporting outliers in compilation to the Burst compiler team (via the [Burst forum](https://forum.unity.com/forums/burst.629/)), but practically there are a few things you might want to consider when reading this output. - The compiler output is split into a few major sections: - Method discovery (where we work out what needs to be compiled) - Frontend (where we turn C# IL into an LLVM IR module) - Middle-end (where we specialize, optimize, and cleanup the module) - Backend (where we turn the LLVM IR module into a native DLL) - The compile time in the frontend and optimizer is normally linear with the amount of stuff needing to be compiled: - More functions and more instructions means a longer compile time - The more generic functions you have, the higher the frontend cost (generic resolution has a non-zero cost) - The compile time in the backend will scale with the number of entry-points in the module (as each entry-point resides in its own native object file) - If the optimizer is taking a significant amount of time, you could consider using `[BurstCompile(OptimizeFor = OptimizeFor.FastCompilation)]` which will reduce the optimizations we do, but compile things much faster. You should profile the job before and after to ensure this tradeoff is right for that entry-point though! # Burst Inspector The Burst Inspector window displays all the Jobs and other Burst compile targets in the project. Open the Inspector from the Jobs menu (**Jobs** > **Burst** > **Open Inspector...**). The inspector allows you to view all the Jobs that can be compiled, you can also then check the generated intermediate and native assembly code. ![Burst Inspector](../images/burst-inspector.png) On the left pane of the window, **Compile Targets** provides an alphabetically sorted list of the Jobs in the project that Burst can compile. Note that the disabled Jobs in the list don't have the `[BurstCompile]` attribute. On the right pane, the window displays options for viewing the assembly and intermediate code for the selected compile target. Note the coloured boxes (some with elipses), these can be clicked on to expand/collapse elements of the code. By default, when using enhanced/coloured output, the inspector will automatically collapse blocks that are consider non essential (ie it collapses away most directives and data, to leave you with just the code). To select text from the right pane of the inspector, simply use the mouse cursor or the keyboard arrows in combination with the shift key. The mouse cursor can be used either to drag over the text, or right clicking and selecting **Select All**. Copying selected text is done either by pressing _ctrl + c_ or right clicking and choosing **Copy Selection**. **To view the disassembly for a Job:** 1. Select an active compile target from the _left pane_. 2. Switch between the different tabs to display the details: * **Assembly** provides the final optimized native code generated by Burst. * **.NET IL** provides a view on the original .NET IL extracted from the Job method. * **LLVM IR (Unoptimized)** provides a view on the internal LLVM IR before optimizations. * **LLVM IR (Optimized)** provides a view on the internal LLVM IR after optimizations. * **LLVM IR Optimization Diagnostics** provides detailed LLVM diagnostics of the optimizations (i.e if they succeeded or failed). 3. You can also turn on different options: * There is a dropdown to specify what output to show. Selecting and copying text will copy the output that matches what you specify here. Note that enhanced and coloured mode is only available for assembly. * **Plain Without Debug Information** - raw output. * **Plain With Debug Information** - same as above but with debug information included too. * **Enhanced With Minimal Debug Information)** - enhanced output has the line information interweaved with the assembly to guide you as to what line in your code matches what assembly output. Furthermore, the branch flow is visualized by arrows indicating where jump instruction might branch off to. * **Enhanced With Full Debug Information** - same as above but with debug information included too. * **Coloured With Minimal Debug Information** - same as the enhanced output but the assembly is colourised nicely to aid reading. * **Coloured With Full Debug Information** - same as above but with debug information included too. * The **Safety Checks** option generates code that includes container access safety checks (e.g check if a job is writing to a native container that is readonly). * Enhanced & Coloured Modes present a few additional buttons detailed here (which are active for assembly views, but not the IL or other tabs: * **Focus on Code** collapses the least important blocks of the disassembly (it hides most of the assembler directives and non code segments), allowing you to focus on the code itself. This is the default, and will be how code is presented when selecting jobs etc. * **Expand all** expands all collapsed blocks of disassembly, showing all the hidden assembler directives and data elements. * The **Show Branch Flow** options toggle whether arrows showing branch flow should be visible or not. When enabled, the code is moved to the right, to make space for the arrows to be drawn. # Command-line Options You can pass the following options to the Unity Editor on the command line to control Burst: - `--burst-disable-compilation` — turns Burst off. - `--burst-force-sync-compilation` — Burst always compiles synchronously. See [`[BurstCompile]` options](AdvancedUsages.md#synchronous-compilation). # Just-In-Time (JIT) vs Ahead-Of-Time (AOT) Compilation When working on your projects in the editor (Play Mode), Burst works in a Just-In-Time (JIT) fashion. Burst will compile your code at the point that it is to be used. By default this is done asnychronously which means your code will be running under the default mono JIT until the compilation by Burst has been completed. You can control this behaviour via [`[BurstCompile]` options](AdvancedUsages.md#synchronous-compilation). However, when you build your project into a Standalone Player, Burst will instead compile all the supported code Ahead-Of-Time (AOT). AOT compilation at present, requires access to some linker tools for the respective platforms (similar to the requirements of IL2CPP). See [Burst AOT Requirements](StandalonePlayerSupport.md#burst-aot-requirements). See [Standalone Player Support](StandalonePlayerSupport.md).