[dmd-internals] Regarding deprecation of volatile statements

Walter Bright walter at digitalmars.com
Tue Jul 24 16:20:53 PDT 2012


On 7/24/2012 3:18 PM, Alex Rønne Petersen wrote:
> On Wed, Jul 25, 2012 at 12:11 AM, Walter Bright <walter at digitalmars.com> wrote:
>> On 7/24/2012 2:53 PM, Alex Rønne Petersen wrote:
>>> But shared can't replace volatile in kernel space. shared means
>>> atomics/memory fences which is not what I want - that would just give me
>>> unnecessary overhead. I want the proper, standard C semantics of volatile,
>>
>> C does not have Standard semantics for volatile. It's a giant mess.
> Right, it leaves the exact definition of a volatile access to the
> compiler.

Right, that's why it is incorrect to refer to it as "standard" behavior. 
Behaviors I've seen include various combinations of:

1. disallowing enregistering
2. preventing folding multiple loads/stores together
3. preventing reordering across expressions with volatiles
4. inserting memory load/store fences



>   But most relevant C compilers have a fairly sane definition
> of this. For example, GCC:
> http://gcc.gnu.org/onlinedocs/gcc/Volatiles.html
>
>>
>>> not the atomicity that people seem to associate with it.
>>
>> Exactly what semantics are you looking for?
> GCC's volatile semantics, pretty much. I want to be able to interact
> with volatile memory without the compiler thinking it can optimize or
> reorder (or whatever) my memory accesses. In other words, tell the
> compiler to back off and leave volatile code alone.

Unfortunately, this is rather vague. For example, how many read/write operations 
are there in v++? Optimizing is a terminally nebulous concept.


D volatile isn't implemented, either.


> It doesn't insert a compiler reordering fence? Martin Nowak seemed to
> think that it does, and a lot of old druntime code assumed that it
> did...

dmd, all on its own, does not reorder loads and stores across accesses to 
globals or pointer dereferences. This behavior is inherited from dmc, and was 
very successful. dmc generated code simply did not suffer from all kinds of 
heisenbugs common with other compilers because of that. I've always considered 
reordering stores to globals as a bad thing to rely on, and not a significant 
source of performance improvements, so deliberately disabled them.

However, I do understand that the D spec does allow a compiler to do this.

Even though shared is not implemented at the low level, I suggest using it 
anyway as it currently does work (with or without shared). You should anyway, as 
the only way there'd be trouble is for multithreaded access to that memory anyway.

As for exact control over read and write cycles, the only reliable way to do 
that is with inline assembler.

Use these two techniques, and your code should be future proofed.



More information about the dmd-internals mailing list