volatile in multithreaded apps

  • Thread starter Thread starter Graeme Prentice
  • Start date Start date
G

Graeme Prentice

Visual studio help has the following code to illustrate the use of
ReadWriteBarrier. What does the volatile keyword do in Visual C++?

Does it ensure the code will work correctly when executed on a machine
with multiple CPUs i.e. that a read of a volatile variable always sees
the most up to date value of a variable and not an out of date value due
to another thread modifying the variable but not having yet updated main
memory from its cache. I don't see any special instructions generated
for the volatile variable access in the compiled code.

Graeme



// cpp_intrin_ReadWriteBarrier.cpp
// compile with: /MD /O2
// add /DUSE_BARRIER to see different results
#include <stdio.h>
#include <process.h> // _beginthread
#include <windows.h>

extern "C" void _ReadWriteBarrier();
#pragma intrinsic(_ReadWriteBarrier)

int G;
int i;

volatile int ReleaseF = 0, WaitF = 0;

void f(void *p)
{
G = 1;

#ifdef USE_BARRIER
_ReadWriteBarrier();
#endif

WaitF = 1;
while (ReleaseF == 0);

G = 2; // Without barrier, the optimizer could remove 'G = 1'...
}

int main()
{
_beginthread(f, 0, NULL); // New thread

while (WaitF == 0) // Wait for change in var waitF
Sleep(1);

if (G == 1)
puts("G is equal to 1, as expected.");
else
puts("G is NOT equal to 1!");

ReleaseF = 1;
}
 
Graeme Prentice said:
Visual studio help has the following code to illustrate the use of
ReadWriteBarrier. What does the volatile keyword do in Visual C++?

Does it ensure the code will work correctly when executed on a machine
with multiple CPUs i.e. that a read of a volatile variable always sees
the most up to date value of a variable and not an out of date value due
to another thread modifying the variable but not having yet updated main
memory from its cache.
if a variable is read, it is always the latest value. wether it is read from
cach or not is not
an issue. this is handled by the CPU itself. the problem is that when you
build your program with optimisation, it is possible for the compiler to
assume that variables are not changed anymore (since they are only changed
by another thread). if that happens, the compiler optimizes the code to not
read certain values again.
the volatile keyword indicates that the compiler should not optimise access
to that variable. this is why you do not see special instructions.

in this case, without the volatile keyword, the compiler would always assume
that ReleaseF and WaitF are false, and optimise away all code that depends
on these variables being true.

kind regards,
Bruno.
 
Back
Top