Singularity/Library/PackageCache/com.unity.burst@1.8.4/Documentation~/optimization-hint.md
2024-05-06 11:45:45 -07:00

2.9 KiB

Hint intrinsics

Use the Hint intrinsics to add information to your code which helps with Burst optimization. It has the following methods:

Likely intrinsic

The Likely intrinsic is most useful to tell Burst which branch condition has a high probability of being true. This means that Burst can focus on the branch in question for optimization purposes:

if (Unity.Burst.CompilerServices.Hint.Likely(b))
{
    // Any code in here will be optimized by Burst with the assumption that we'll probably get here!
}
else
{
    // Whereas the code in here will be kept out of the way of the optimizer.
}

Unlikely intrinsic

The Unlikely intrinsic tells Burst the opposite of the Likely intrinsic: the condition is unlikely to be true, and it should optimize against it:

if (Unity.Burst.CompilerServices.Hint.Unlikely(b))
{
    // Whereas the code in here will be kept out of the way of the optimizer.
}
else
{
    // Any code in here will be optimized by Burst with the assumption that we'll probably get here!
}

The Likely and Unlikely intrinsics make sure that Burst places the code most likely to be hit after the branching condition in the binary. This means that the code has a high probability of being in the instruction cache. Burst can also hoist the code out of the likely branch and spend extra time optimizing it, and not spend as much time looking at the unlikely code.

An example of an unlikely branch is to check if result of an allocation is valid. The allocation is valid most of all the time, so you want the code to be fast with that assumption, but you want an error case to fall back to.

Assume intrinsic

The Assume intrinsic is powerful. Use it with caution because it tells Burst that a condition is always true.

Warning

When you use Assume, Burst assumes the value is true without checking whether it's true.

Unity.Burst.CompilerServices.Hint.Assume(b);

if (b)
{
    // Burst has been told that b is always true, so this branch will always be taken.
}
else
{
    // Any code in here will be removed from the program because b is always true!
}

Use the Assume intrinsic to arbitrarily tell Burst that something is true. For example, you can use Assume to tell Burst to assume that a loop end is always a multiple of 16, which means that it can provide perfect vectorization without any scalar spilling for that loop. You could also use it to tell Burst that a value isn't NaN, or it's negative.