Paul Koning wrote:
"Robert" == Robert Dewar <[EMAIL PROTECTED]> writes:
Robert> Ken Raeburn wrote:
>> That's what I thought. So, unless the compiler (or language spec)
>> is going to become thread-aware, any data to be shared across
>> threads needs to be declared volatile, even if some other
>> mechanism (like a mutex) is in use to do some synchronization.
>> Which means performance would be poor for any such data.
Robert> The use of shared variables without synchronization is rare
Robert> in any case in most code.
You mean "without explicit synchronization" via mutexes or the like?
It seems that the classic circular buffer communication mechanisms
have been forgotten by many, but they still work quite well and
require no mutexes or the like. All that is required is sufficiently
ordered memory accesses.
Sure such alogorithms are interesting on mono processors, and that's
EXACTLY the situation in which volatile is appropriate (there is a bit
of confusion in C between what Ada would call volatile and atomic. In
Ada, volatile talks about making sure that reads/writes are to memory,
and atomic is about guaranteeing that access takes a single instruction.
For example, in Ada programming the circular buffer works by making the
buffer itself volatile, and the pointers to the buffer atomic. I am not
sure exactly how this works in C, or whether it is really well defined).
Actually shared variables are quite an interesting topic. If you want
to find out much more about them, have a look at Norman Shulman's NYU
PhD thesis (I was the advisor) which is all about shared variables.
Not sure if it is online somewhere or not. There are a number of
interesting algorithms discussed in this thesis, including the class
of algoritms where different threads work on different parts of a
matrix with overlapped shared variables on the edges.
Nevertheless such usage is relatively rare, and volatile is good enough,
I see no basis for any changes to the compiler.
I'm using circular buffers to communicate between threads. I drop
data into the buffer and move the "in" pointer; the consumer compares
the pointers, reads data from the buffer, and advances the "out"
pointer. The current code has the pointers declared as volatile, buf
the buffer data area is not (and I wouldn't want it to be -- that
seems to be a performance issue).
Of course the buffer data area must be declared as volatile, otherwise
the compiler is free to make and hold private copies of elements in
separate threads. It probably won't in practice, but to rely on this
is non-portable.
So this relies on volatile references acting as barriers to the
movement of non-volatile references.
There is no basis for such reliance
In a coherent memory system (or
single CPU platform) that's sufficient; in a non-coherent or weakly
enough ordered system I would add asm("sync") or the like.
You miss the important point that it is just fine for individual
threads to make local copies of memory variables, e.g. in registers,
and so the reads/writes that you expect to be syncrhonized in this way
just aren't there at all.
paul