Trying to edit a single variable using an IJobParallelFor job

Hey.

I have a job that tries to count valid pixels in a texture and save it into a NativeArray with a single variable inside it. Every time I run the job I get a different result even though the inputs are the same. Here’s an example simplified version of my job:

struct ExampleJob : IJobParallelFor
{
    [NativeDisableParallelForRestriction] public NativeArray<ulong> validPixels;

    public void Execute(int index)
    {
        if(some condition is true)
            validPixels[0] = validPixels[0] + 1;
    }
}

Even if the condition is always true, the result will be different every time. I assume this is caused by a race condition since I constantly try to read and write into validPixels[0].

It’s impossible to use a lock or any other methods that depend on references. Is there any solution to this problem? Thanks

There’s an example of a NativeCounter in the jobs manual that sounds like it does what you want

https://docs.unity3d.com/Packages/com.unity.jobs@0.11/manual/custom_job_types.html#custom-nativecontainers

I’ll check it out. Thanks!

It probably depends on your condition. If it is false 99% of the time an interlocked increment might be a good idea. If it’s true most of the time you should do what @tertle said or just use a single thread.

Quick fix to get the correct result:

  1. make your validPixels long instead of ulong.
ref var counter = ref UnsafeUtility.ArrayElementAsRef<long>(validPixels.GetUnsafePtr(), 0);
Interlocked.Increment(ref counter);

The condition’s true rate will be between 0 to 100% depending on various other variables, so I ended up using the native container provided by @tertle . This saved me a lot of trouble, thanks a lot!