DIP 1024--Shared Atomics--Community Review Round 1

Ola Fosheim Grøstad ola.fosheim.grostad at gmail.com
Sun Oct 13 07:54:20 UTC 2019


On Sunday, 13 October 2019 at 04:09:26 UTC, Jonathan M Davis 
wrote:
> The compiler is free to assume that anything that isn't shared 
> is thread-local and optimize code accordingly.

That has no real effect though, if you throw away shared before 
using it.

That said, if you had a formalization of the threads and what 
states different threads are in then you could get some 
performance benefits by eliding shared overhead when it can be 
proven that no other threads are accessing a shared variable.

But that is not on the table...

> Also, it _does_ matter on some level with how memory is laid 
> out, because thread-local storage gets used (IIRC, there were 
> problems on older versions of OS X, because we had to fake the 
> TLS, because OS X didn't provide proper TLS).

Actually, how the memory is laid out is not a big deal. Vendors 
can do this with a library solution too. What is a big deal with 
TLS is that you need different codegen for obtaining a reference, 
but that also mean that you cannot throw away that type 
information before you have a obtained an effective address 
(reference)?

Same thing with shared. On an architecture that requires a 
different instruction sequences for shared memory and local 
memory, you would need to retain that information. Not for 
allocation, which can be dealt with at the library level, but for 
accessing it when executing generic functions.

If anything that would be an argument for never being allowed to 
throw away the shared marker, and also an argument for being able 
to add more markers (for different types of memory or I/O).


> Module-level and static variables which are shared only get 
> initialized once, whereas module-level and static variables 
> which are thread-local get initialized once per thread, because 
> each thread gets their own copy.

I'd rather say that a TLS variable "value" is conceptually 
"value[thread_id]" or "value__12345".


> Fortunately, as long as shared disallows non-atomic, read/write 
> operations the code that needs to be examined for threading 
> issues is restricted to @system/@trusted code that involves 
> shared, so the amount of code that the programmer has to 
> examine and verify to ensure that shared data doesn't end up 
> being treated as thread-local when multiple threads can operate 
> on it is limited and should be fairly easy to find.

And you can achieve all that with a library type, because D 
doesn't actually deal with shared memory, it provides some 
instructions that results in barriers in the IR.

If you wrap all those barrier-generating instructions in library 
calls then they can just avoid emitting them if the type they are 
applied to is not wrapped in a  library provided Shared wrapper.

I don't see why the compiler has to know anything about shared 
for this to work the same way as described.

Anyway, I think D really needs to think twice about adding more 
and more narrow features and instead improve on the meta 
programming capabilities. Clearly many D features could be moved 
to the library (slicing, dicts etc).

If there is a limited pool of people working on the compiler it 
would make a lot of sense to put more power into the hands of 
library authors.  The meta-programming capabilities of C++ is 
evolving too...



More information about the Digitalmars-d mailing list