Question

I'm looking at this bit of text in the documentation for Visual C++'s _ReadWriteBarrier intrinsic:

In past versions of the Visual C++ compiler, the _ReadWriteBarrier and _WriteBarrier functions were enforced only locally and did not affect functions up the call tree. In Visual C++ 2005 and later, these functions are enforced all the way up the call tree.

I understand what the barrier does within a function, but the "up the call tree" seems to imply that a function foo() calling a function bar() can know whether bar() contains a barrier or not. What actually changed in VC2005 to enable this... the calling convention/ABI, some global analysis done by the compiler, or what ?

Was it helpful?

Solution

MS docs are never great, and this one is a good example of that. There are 2 parts to the _ReadWriteBarrier:

  1. telling the CPU to do a memory barrier (ie mfence),
  2. telling the compiler not to optimize around the barrier.

I suspect the call tree part is referring to #2. ie:

int x = 0;

void foo()
{
   x = 7;
   _ReadWriteBarrier();
   x = 8;
}

Without the barrier, x=7 can be completely removed by the compiler. With the barrier, it stays. Now, what about a function that calls foo?

void bar()
{
   x = 3;  // optimized away?
   foo();
   x = 4;
}

I think in the past x=3 might have been optimized away (which can be hard for the compiler to tell whether that's allowed or not), but now it will correctly keep the x=3 instructions.

I think.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top