volatile

General OpenMP discussion

volatile

Postby Hans.Boehm@hp.com » Sat Dec 29, 2007 10:19 am

I noticed that the treatment of "volatile", near the end of 1.4,2, on page 15, seems largely unchanged. I do not understand the rationale for the current definition, and it is completely at odds with similar constructs in other languages.

Consider the following canonical task: I want to initialize a variable x in one thread, set a flag x_init that the initialization is done, and then read the initialization flag and the variable in another thread. In Java, I could write something like:

volatile boolean x_init; // x_init simultaneously accessed from multiple threads;
// hence volatile.
Thread 1:
x = ...
x_init = true;

Thread 2:
while (!x_init) {}
... = x;

and by the rules of the Java memory model, I would be guaranteed to see x properly initialized. On weakly ordered machines that use fences in the implementation, this is accomplished by compiling to code that looks vaguely like (simplifying a bit, since the fence should really be at the end of the loop conidition, but it doesn't matter):

Thread 1:
x = ...
fence();
x_init = true;

Thread 2:
while (!x_init) {}
fence();
... = x;

Based on the preceding section, I think that flush should be used similarly. If I write (taking great liberties with the OpenMP syntax):

Thread 1:
x = ...
flush();
x_init = true;

Thread 2:
while (!x_init) {}
flush();
... = x;

(The flush could possibly specify x as a parameter, though I suspect that is almost never adequate for real code, which would typically initialize a more complex data structure that probably couldn't be named.)

However, if we were to start with the Java program, and apply the OpenMP definition of volatile, we get something roughly like:

Thread 1:
x = ...
x_init = true;
flush(x_init);

Thread 2:
while (flush(x_init), !x_init) {}
... = x;

Clearly both flushes are useless here, and there is nothing to prevent an uninitialized value of x from being seen.

In this case, this might work if I declared x volatile instead (or in addition). But that's undesirable for two reasons:

1. As mentioned above, it doesn't work in practice, since real code would be initializing a more complex data structure, some of which could probably not be named here, due to abstraction boundaries.

2. It's inconsistent with other languages. Java uses volatile as described above. C and C++ volatiles are officially not meant for use with threads, and unofficially have widely varying semantics when (mis)used that way. The proposed C++ atomics behave like Java volatiles.

I'm particularly worried about the language inconsistency since I suspect that in reality many implementations will use similar backends with and without OpenMP.

Hans


Last bumped by Anonymous on Sat Dec 29, 2007 10:19 am.
Hans.Boehm@hp.com
 

Return to Using OpenMP

Who is online

Users browsing this forum: Exabot [Bot] and 5 guests