volatile in multithreaded apps

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;
}
 
B

Bruno van Dooren

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.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top