I am still wrapping my head around burst sometimes, and wanted to see if someone can explain the messages I get. Latest burst on Unity 2022.3.27f1
Messages:
-
loop not vectorized: instruction return type cannot be vectorized
-
loop not vectorized: value that could not be identified as reduction is used outside the loop
-
I do not know why it cannot be vectorized further. I do already use vectors, but shouldn’t it add this to float3x3 or float 3x4 for more SIMD?
-
No idea what this means exactly. Could someone elaborate?
-
I thought using the math library would be faster, or would it be faster to only set the values minDistanceSqr and nearestVertexHeight in an if statement instead?
Here is the code to sample a mesh:
[BurstCompile]
public struct EffectsJobParralel : IJobParallelFor
{
[ReadOnly]
public NativeArray<float3> Vertices;
[ReadOnly]
public float3 CenterPosition;
[ReadOnly]
public float Radius;
[WriteOnly]
public NativeArray<float3> SpawnPositions;
public void Execute(int index)
{
float3 position = CenterPosition + new float3(math.cos(index * 2 * math.PI / 50), 0, math.sin(index * 2 * math.PI / 50)) * Radius;
float minDistanceSqr = float.MaxValue;
float nearestVertexHeight = 0;
for (int j = 0; j < Vertices.Length; j++)
{
float3 vertex = Vertices[j];
float distanceSqr = math.distancesq(position.xz, vertex.xz);
bool picker = distanceSqr < minDistanceSqr && vertex.y < 1.7f;
minDistanceSqr = math.select(minDistanceSqr, distanceSqr, picker);
nearestVertexHeight = math.select(nearestVertexHeight, vertex.y, picker);
}
SpawnPositions[index] = new float3(position.x, nearestVertexHeight, position.z);
}
}
Can only give some pointers. These Burst statements are sometimes vague and sometimes require a deep understanding of SIMD and how Burst optimizes, or what makes it fail to optimize, or whether it’s just an expected statement that cannot be “fixed”.
I don’t see much that could be vectorized here to begin with. The less-than conditionals likely break any such optimization because every loop iteration depends on the current value of minDistanceSqr and nearestVertexHeight.
What you could do to allow this code to be vectorized is to run a loop that merely calculates distanceSqr, and put it in a list. Then have a second loop that performs the distance checks. The first loop will be vectorized, the second won’t. It’s still possible that it’ll run faster overall but I don’t think this has much effect.
I’d think that the compiler optimizes this in release but if not and in case the message is because of this optimization not happening in debug builds, it can’t hurt to pull Vertices.Length out before the loop and assign it to a var to avoid the repeated property access.
Other notes:
The ReadOnly/WriteOnly attributes only apply to collections. You can remove them from CenterPosition and Radius.
Prefer to use the ‘var’ keyword. It’s just nicer to read and write, as it deduplicates statements like “float3 x = new float3()”.
Pull this repeated calculation out from first line: index * 2 * math.PI / 50
Compiler may or may not optimize it, but either way it’s just bloating that line to unnecessary length.
1 Like
Thanks a lot for the insights!
I was also thinking of using 2 loops but did not think it would be worth it right now. I barely fit this onto the quest 3’s CPU at the moment for a hackathon, so probably will keep it.
Good to cache the vert length as well. Thanks for the feedback 
I think it works better with multiplication of 4 so float4 or float4x4. But you have to figure out where that can be used.
Unwrapping function helps in figuring this out too ie. Distance. But alot of these algorithms cant be vectorized.