Googles appar
Huvudmeny

Post a Comment On: cbloom rants

"01-25-09 - Low Level Threading Junk Part 1"

5 Comments -

1 – 5 of 5
Anonymous Anonymous said...

again on x86 volatile means extra things, for example volatile memory accesses won't get reordered, but don't rely on that

I don't think this is true; when ANSI introduced volatile they also introduced this whole "sequence point" construction to allow them to specify control over ordering, and I can't remember it being used for anything except volatile. Also, volatile was (IIRC) introduced to allow communicating with hardware through memory, so obviously the order of operations is crucial.

So I thought the guarantee of volatile was that all volatile reads and writes have to happen in fixed order, and none can be suppressed or duplicated.

Of course, presumably this is only implemented in the compiler output stream, and it doesn't force the hardware to do anything -- it doesn't output barriers the hardware might need, etc (although I think technically one could argue that this is a bug, since then the implementation isn't actually doing what ANSI specified, and I don't think ANSI distinguishes the compiler from the final execution).

January 25, 2009 at 11:14 PM

Blogger MaciejS said...

Cost of memory barrier varies from platform to platform, it actually is not that bad on X360 (quicker than most interlocked ops for example).

January 26, 2009 at 12:27 AM

Blogger Tom Forsyth said...

I seem to recall that "volatile" is simply a compiler directive on ordering/enregistering. It does not cause memory barrier instructions to be emitted.

On x86, there are many strong guarantees on the ordering of memory accesses w.r.t. the ordering of the assembly you write (there's a big document somewhere detailing exactly what you can expect), so using volatile is 90% of what you need. On processors like Alpha or Itanium where the ordering of memory has very little to do with the order the assembly instructions are in, using volatile is not enough - you need explicit memory barriers.

January 26, 2009 at 3:10 AM

Blogger cbloom said...

http://en.wikipedia.org/wiki/Memory_barrier

Wikipedia says "volatile" memory accesses cannot be reordered against each other by the compiler. But they can be reordered against nonvolatile memory access. And it gives no guarantees about the CPU or memory system reordering.

x86 is special because the x86 cpu will never reorder stores vs stores or reads vs reads. (note that this is only true for scalar code on Intel, SSE load/stores do not have these strict semantics)

Furthermore, MSVC volatile is special because after 2005 they automatically ensure volatile reads are Acquire and volatile writes are Release. That would be sweet if it was consistent, but even MSVC on Xenon doesn't do that.

But as I say I think the best thing is to explicitly indicate where barriers of various kinds are needed in the code rather than relying on the inconsistent magic of volatile.

C++0x will probably have some kind of "atomic" keyword which is what you want volatile to be.

January 26, 2009 at 9:57 AM

Blogger Action Man (the greatest hero of them all) said...

Regarding MemoryBarrier vs _ReadWriteBarrier:

Apparently MemoryBarrier *may* prevent compile-time reordering, but is not guaranteed to.

If this is the case, and if _ReadWriteBarrier doesn't have a run-time cost, then I would recommend using both of these together when a full-fence is required.

There's lots of detail in "Lockless Programming Considerations for Xbox 360 and Microsoft Windows" (http://msdn.microsoft.com/en-us/library/ee418650%28VS.85%29.aspx)

May 13, 2010 at 1:57 AM

You can use some HTML tags, such as <b>, <i>, <a>

This blog does not allow anonymous comments.

Comment moderation has been enabled. All comments must be approved by the blog author.

You will be asked to sign in after submitting your comment.