Search code examples
c#multithreadingvolatilegetterinstruction-reordering

Does Volatile.Read() still apply if it is nested in a getter?


Consider this code in C#:

private int _backingField;

public int SomeNumber => Volatile.Read(ref _backingField);

public void Test_1()
{
    var someNumber = Volatile.Read(ref _backingField);

    // do A

    if (someNumber == 5)
    {
        // do B
    }
}

public void Test_2()
{
    var someNumber = SomeNumber;

    // do A

    if (someNumber == 5)
    {
        // do B
    }
}

I am aware that modern CPUs, in order to improve performance, do lots of optimizations under the hood. One of those optimizations might include moving the assignment to someNumber AFTER the // do A line if no Volatile.Read() is used.

My question is, however, is whether the Test_1 and Test_2 methods are identical. Does the fact that Test_2's volatile read is nested in a getter nullify the benefits of the volatile read?


Solution

  • The Test_1 and Test_2 are identical. In both cases the var someNumber is a volatile read, meaning that the following instructions (// do A) cannot be moved before this read by the compiler, Jitter or CPU processor. It doesn't matter if the Volatile.Read(ref _backingField) is called directly or indirectly. The memory barrier is placed either way.