On 14 November 2012 19:54, Andrei Alexandrescu <span dir="ltr"><<a href="mailto:SeeWebsiteForEmail@erdani.org" target="_blank">SeeWebsiteForEmail@erdani.org</a>></span> wrote:<br><div class="gmail_extra"><div class="gmail_quote">
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div class="im">On 11/14/12 9:31 AM, David Nadlinger wrote:<br>

<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
On Wednesday, 14 November 2012 at 15:08:35 UTC, Andrei Alexandrescu wrote:<br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
Sorry, I was imprecise. We need to (a) define intrinsics for loading<br>
and storing data with high-level semantics (a short list: acquire,<br>
release, acquire+release, and sequentially-consistent) and THEN (b)<br>
implement the needed code generation appropriately for each<br>
architecture. Indeed on x86 there is little need to insert fence<br>
instructions, BUT there is a definite need for the compiler to prevent<br>
certain reorderings. That's why implementing shared data operations<br>
(whether implicit or explicit) as sheer library code is NOT possible.<br>
</blockquote>
<br>
Sorry, I didn't see this message of yours before replying (the perils of<br>
threaded news readers…).<br>
<br>
You are right about the fact that we need some degree of compiler<br>
support for atomic instructions. My point was that is it already<br>
available, otherwise it would have been impossible to implement<br>
core.atomic.{atomicLoad, atomicStore} (for DMD inline asm is used, which<br>
prohibits compiler code motion).<br>
</blockquote>
<br></div>
Yah, the whole point here is that we need something IN THE LANGUAGE DEFINITION about atomicLoad and atomicStore. NOT IN THE IMPLEMENTATION.<br>
<br>
THIS IS VERY IMPORTANT.</blockquote><div><br></div><div>I won't outright disagree, but this seems VERY dangerous to me.</div><div><br></div><div>You need to carefully study all popular architectures, and consider that if the language is made to depend on these primitives, and the architecture doesn't support it, or support that particular style of implementation (fairly likely), than D will become incompatible with a huge number of architectures on that day.<br>
</div><div><br></div><div>This is a very big deal. I would be scared to see the compiler generate intrinsic calls to atomic synchronisation primitives. It's almost like banning architectures from the language.</div><div>
<br></div><div>The Nintendo Wii for instance, not an unpopular machine, only sold 130 million units! Does not have synchronisation instructions in the architecture (insane, I know, but there it is. I've had to spend time working around this in the past).</div>
<div>I'm sure it's not unique in this way.</div><div><br></div><div>People getting fancy with lock-free/atomic operations will probably wrap it up in libraries. And they're not globally applicable, atomic memory operations don't magically solve problems, they require very specific structures and access patterns around them. I'm just not convinced they should be intrinsics issued by the language. They're just not as well standardised as 'int' or 'float'.<br>
</div><div><br></div><div><div>Side note: I still think a convenient and fairly practical solution is to make 'shared' things 'lockable'; where you can lock()/unlock() them, and assignment to/from shared things is valid (no casting), but a runtime assert insists that the entity is locked whenever it is accessed.<i> </i>It's simplistic, but it's safe, and it works with the same primitives that already exist and are proven. Let the programmer mark the lock/unlock moments, worry about sequencing, etc... at least for the time being. Don't try and do it automatically (yet).</div>
</div><div>The broad use cases in D aren't yet known, but making 'shared' useful today would be valuable.<br></div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
<div class="im">
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
Thus, »we«, meaning on a language level, don't need to change anything<br>
about the current situations, with the possible exception of adding<br>
finer-grained control to core.atomic.MemoryOrder/mysnc [1]. It is the<br>
duty of the compiler writers to provide the appropriate means to<br>
implement druntime on their code generation infrastructure – and indeed,<br>
the situation in DMD could be improved, using inline asm is hitting a<br>
fly with a sledgehammer.<br>
</blockquote>
<br></div>
That is correct. My point is that compiler implementers would follow some specification. That specification would contain informationt hat atomicLoad and atomicStore must have special properties that put them apart from any other functions.<div class="im">
<br>
<br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
David<br>
<br>
<br>
[1] I am not sure where the point of diminishing returns is here,<br>
although it might make sense to provide the same options as C++11. If I<br>
remember correctly, D1/Tango supported a lot more levels of<br>
synchronization.<br>
</blockquote>
<br></div>
We could start with sequential consistency and then explore riskier/looser policies.<span class=""><font color="#888888"><br>
<br>
<br>
Andrei<br>
</font></span></blockquote></div><br></div>