Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Question How to avoid race condition when accessing NativeReference in parallel?

Discussion in 'C# Job System' started by Balphagore, Apr 14, 2023.

  1. Balphagore

    Balphagore

    Joined:
    Jul 18, 2019
    Posts:
    81
    Hi all. I want to figure out how to correctly change NativeReference<int> simultaneously from several threads.

    Code (CSharp):
    1. using UnityEngine;
    2. using Unity.Jobs;
    3. using Unity.Collections;
    4.  
    5. public class ParallelJobsExample : MonoBehaviour
    6. {
    7.     private void Start()
    8.     {
    9.         NativeReference<int> result = new NativeReference<int>(Allocator.TempJob);
    10.  
    11.         JobHandle jobHandle = new MyJob()
    12.         {
    13.             result = result,
    14.         }.Schedule(128, 64);
    15.  
    16.         jobHandle.Complete();
    17.  
    18.         Debug.Log(result.Value);
    19.  
    20.         result.Dispose();
    21.     }
    22.  
    23.     private struct MyJob : IJobParallelFor
    24.     {
    25.         [NativeDisableParallelForRestriction]
    26.         public NativeReference<int> result;
    27.  
    28.         public void Execute(int index)
    29.         {
    30.             result.Value++;
    31.         }
    32.     }
    33. }
    This option generally works, but causes a race condition in which different threads write to the same place. As a result, the final value of result is less than expected. How can this be avoided? It's a pity without using unsafe code.
     
  2. DreamingImLatios

    DreamingImLatios

    Joined:
    Jun 3, 2017
    Posts:
    3,984
    You'll need unsafe code and Interlocked.Add.
     
    Balphagore likes this.
  3. Balphagore

    Balphagore

    Joined:
    Jul 18, 2019
    Posts:
    81
    I have seen such options, but I would like an option without unsafe code. Are there really none?
     
  4. brunocoimbra

    brunocoimbra

    Joined:
    Sep 2, 2015
    Posts:
    677
    There is an AtomicCounter in the Unity.Collections
     
    vectorized-runner likes this.
  5. vectorized-runner

    vectorized-runner

    Joined:
    Jan 22, 2018
    Posts:
    383
    I mean this is not a NativeReference problem, it's the multithreading problem 101. AtomicCounter has a cool solution by using per thread accumulators which is faster than Interlocked.Add.