Synchronization and volatile

G

George2

Hello everyone,


Through myself study and previous discussion here, I share the
conclusion here that,

if some object is synchronized (mutex, critical section, etc.), there
is no need to add volatile keyword.

Here is the reference,

(refer to section volatile, Critical Sections, and Race Conditions)

http://www.ddj.com/cpp/184403766

if my understanding is wrong or you have any other options, please
feel free to add here.


thanks in advance,
George
 
R

Rahul

Hello everyone,

Through myself study and previous discussion here, I share the
conclusion here that,

if some object is synchronized (mutex, critical section, etc.), there
is no need to add volatile keyword.

Here is the reference,

(refer to section volatile, Critical Sections, and Race Conditions)

http://www.ddj.com/cpp/184403766

if my understanding is wrong or you have any other options, please
feel free to add here.

thanks in advance,
George

well, i don't agree with that statement.

mutex, semaphore are methods to avoid race condition in pre-emptive
scheduling

volatile is just to make sure compiler doesn't perform any
optimization on the code and makes sure that instructions are
assembled so that the value of the variable is read from the actual
memory every single time...
 
P

Pavel Shved

Hello everyone,

Through myself study and previous discussion here, I share the
conclusion here that,

if some object is synchronized (mutex, critical section, etc.), there
is no need to add volatile keyword.

Here is the reference,

(refer to section volatile, Critical Sections, and Race Conditions)

http://www.ddj.com/cpp/184403766

if my understanding is wrong or you have any other options, please
feel free to add here.
The main idea of the article was that, if you add volatile keyword if
and only if the object is shared (!), you gain lots of benifits from
(partial) pre/postcondition checking, one of the most powerful things
we love in C++ (though we barely know its true name).

Note the difference between `shared' and `thread-safe'. That's not
the same neither it's intenden to be. Reading about these higher
matters you've missed the basic volatile purpose. You need `volatile'
in the case described because whole your thread-safe object could be
cached into processor's registers and every thread would have its own
copy of the _shared_ _thread-safe_ object.
 
J

James Kanze

Through myself study and previous discussion here, I share the
conclusion here that,
if some object is synchronized (mutex, critical section,
etc.), there is no need to add volatile keyword.

Correct. And if the object isn't synchronized, you can't access
it from multiple threads if any thread may modify it, even if it
is declared volatile. The moral is that without
synchronization, volatile isn't enough, and with
synchronization, volatile isn't necessary.

Arguably, this is only because compiler writers ignore the
intent of volatile, and don't implement it, but whatever the
reason, that's the way it is.
Here is the reference,
(refer to section volatile, Critical Sections, and Race Conditions)

if my understanding is wrong or you have any other options,
please feel free to add here.

That's one of Andrei's most interesting articles. It was longly
discussed shortly after it appeared; in the discussion, Andrei
himself admitted that he had misunderstood volatile somewhat,
and the guarantees it gives (and doesn't give). The basic idea
in the article is sound (and in some ways brilliant), because it
doesn't count on any semantics for volatile, but only on the way
volatile works within the type system. I wouldn't use the
article as a basis for understanding volatile semantics,
however.
 
J

James Kanze

[...]
well, i don't agree with that statement.

The statement is certainly correct for Posix, and I can't
imagine it not holding under Windows either. Most multithreaded
programs will never use volatile.
mutex, semaphore are methods to avoid race condition in
pre-emptive scheduling

Amongst other things. According to the Posix specification,
functions like pthread_mutex_lock and pthread_mutex_unlock must
also ensure memory synchronization (between threads *and*
between processes). If they didn't, multithreaded code couldn't
be made to work.
volatile is just to make sure compiler doesn't perform any
optimization on the code and makes sure that instructions are
assembled so that the value of the variable is read from the
actual memory every single time...

Maybe. The exact semantics of volatile are implementation
defined. And some of the more frequently used compilers (VC++,
g++, Sun CC) basically treat volatile as hardly more than a
comment, giving it essentially no useful additional semantics
what so ever (other than making the code slower).

If you're writing code for a multithreaded environment, you need
a compiler which supports multithreading. It's difficult: the
C++ standard, at least the last official version of the C++
standard, doesn't say anything about multi-threading, and most
of the threading standards (e.g. Posix) don't specify a C++
binding, so you're left to exterpolating the C binding to C++.
For some things, the exterpolation is obvious: an int in C++
should behave like an int in C, for example. For others,
however... under Solaris, Sun CC and g++ have very different
behavior in some circumstances (pthread_exit(), for example, or
construction of a local static variable). With regards to code
movement and volatile, however, the exterpolation is rather
straight forward. Posix gives volatile no meaning for
multithreading in C, so there's no reason to expect it to have
meaning in C++. And Posix forbids a Posix-conformant compiler
from moving memory accesses accross a certain number of critical
functions, such as pthread_mutex_lock---it seems reasonable to
expect a C++ compiler which claims Posix compliance to repect
this rule as well. (In practice, most compilers respect it
implicitely anyway, because they're not capable of optimizing
through a function for which they have no sources.)
 
J

James Kanze

[...]
Note the difference between `shared' and `thread-safe'.
That's not the same neither it's intenden to be. Reading
about these higher matters you've missed the basic volatile
purpose. You need `volatile' in the case described because
whole your thread-safe object could be cached into processor's
registers and every thread would have its own copy of the
_shared_ _thread-safe_ object.

That may be its purpose, but as it is implemented in most common
compilers, it doesn't guarantee that. Modern processors have a
lot of registers which the program can't access directly, e.g.
in the pipeline. Ensuring that a value is not in the pipeline
requires special machine instructions: the use of a lock prefix
in i86, a membar instruction in Sparc, etc. None of the
compilers I've tried (VC++, g++ and Sun CC) generate this extra
code for accesses to volatile, so basically, volatile is nothing
but a comment. Or a hook into the type system, which is what
Andrei's code depends on.
 

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

Members online

No members online now.

Forum statistics

Threads
473,995
Messages
2,570,226
Members
46,815
Latest member
treekmostly22

Latest Threads

Top