May 27, 2017 Re: std.functional.memoize : thread local or __gshared memoization? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jonathan M Davis | On Thursday, 25 May 2017 at 14:56:25 UTC, Jonathan M Davis wrote:
> But we do need to get this ironed out well enough that we can definitely tell folks that shared is what it's going to be so that they'll stop using __gshared all over the place to try and work around shared - or at least if they do so, they won't be able to do so with the excuse that shared is not complete.
People don't have to use shared, D supports old good "anything can be shared" C model, if people think C model is good enough for them, they can use it.
|
May 27, 2017 Re: std.functional.memoize : thread local or __gshared memoization? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Kagamin | On Saturday, May 27, 2017 07:20:10 Kagamin via Digitalmars-d wrote:
> On Thursday, 25 May 2017 at 14:56:25 UTC, Jonathan M Davis wrote:
> > But we do need to get this ironed out well enough that we can definitely tell folks that shared is what it's going to be so that they'll stop using __gshared all over the place to try and work around shared - or at least if they do so, they won't be able to do so with the excuse that shared is not complete.
>
> People don't have to use shared, D supports old good "anything can be shared" C model, if people think C model is good enough for them, they can use it.
Actually, not so much, because in D, most variables are _not_ shared across threads (unlike in C). The compiler is free to assume that if a variable is not marked as shared, it's thread-local, and it can optimize accordingly. Using __gshared on anything other than C globals is just begging for trouble. As such, the fact that D programmers frequently decide to use __gshared in order to avoid dealing with the restrictions with shared is actually extremely bad. You can get away with it in some cases, but it's error-prone and is only going to get worse as the compiler improves. As such, I'd strongly argue that using __gshared with anything other than actual C globals is a serious code smell, and it's a practice that should be actively discouraged.
- Jonathan M Davis
|
May 27, 2017 Re: std.functional.memoize : thread local or __gshared memoization? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jonathan M Davis | On Saturday, 27 May 2017 at 10:02:35 UTC, Jonathan M Davis wrote:
> As such, the fact that D programmers frequently decide to use __gshared in order to avoid dealing with the restrictions with shared is actually extremely bad. You can get away with it in some cases, but it's error-prone and is only going to get worse as the compiler improves.
Hm, I would think that using __gshared would not be affected by compiler improvements, since it would turn off optimizations that assume that the variable doesn't change between reads?
|
May 27, 2017 Re: std.functional.memoize : thread local or __gshared memoization? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ola Fosheim Grøstad | On Saturday, 27 May 2017 at 10:29:05 UTC, Ola Fosheim Grøstad wrote:
> On Saturday, 27 May 2017 at 10:02:35 UTC, Jonathan M Davis wrote:
>> As such, the fact that D programmers frequently decide to use __gshared in order to avoid dealing with the restrictions with shared is actually extremely bad. You can get away with it in some cases, but it's error-prone and is only going to get worse as the compiler improves.
>
> Hm, I would think that using __gshared would not be affected by compiler improvements, since it would turn off optimizations that assume that the variable doesn't change between reads?
Nope. __gshared isn't even part of the type so it can't do that.
__gshared int a;
void main()
{
foo(a);
}
void foo(ref int b)
{
// No way of knowing that b actually
// references __gshared memory.
}
__gshared is a way of declaring a C-like global variable, but D does not - in general - support accessing it in a C-like way. My advice is to cast to shared before use, unless you're totally sure you know what other threads will be doing.
|
May 27, 2017 Re: std.functional.memoize : thread local or __gshared memoization? | ||||
---|---|---|---|---|
| ||||
Posted in reply to John Colvin | On Saturday, 27 May 2017 at 11:52:04 UTC, John Colvin wrote: > Nope. __gshared isn't even part of the type so it can't do that. > > __gshared int a; > > void main() > { > foo(a); But this should fail since foo doesn't take shared? > __gshared is a way of declaring a C-like global variable, but D does not - in general - support accessing it in a C-like way. My advice is to cast to shared before use, unless you're totally sure you know what other threads will be doing. Why isn't it always typed as shared? |
May 27, 2017 Re: std.functional.memoize : thread local or __gshared memoization? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jonathan M Davis | On Saturday, 27 May 2017 at 10:02:35 UTC, Jonathan M Davis wrote: > Actually, not so much, because in D, most variables are _not_ shared across threads (unlike in C). If you don't share data, you don't need to worry how to share data. But if you do, D supports C model. > The compiler is free to assume that if a variable is not marked as shared, it's thread-local, and it can optimize accordingly. Just like in C. > Using __gshared on anything other than C globals is just begging for trouble. Just like in C. > As such, I'd strongly argue that using __gshared with anything other than actual C globals is a serious code smell, and it's a practice that should be actively discouraged. You can't just discourage to write code. What to do instead, open a bakery? |
May 27, 2017 Re: std.functional.memoize : thread local or __gshared memoization? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ola Fosheim Grøstad | On Saturday, 27 May 2017 at 10:29:05 UTC, Ola Fosheim Grøstad wrote:
> Hm, I would think that using __gshared would not be affected by compiler improvements, since it would turn off optimizations that assume that the variable doesn't change between reads?
Like volatile? Volatile doesn't work. Why would you want that? __gshared has purpose to behave like old good global variable simply to provide a low level feature for a system language, if you need something else, then use the right tool.
|
May 27, 2017 Re: std.functional.memoize : thread local or __gshared memoization? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Kagamin | On Saturday, 27 May 2017 at 16:19:06 UTC, Kagamin wrote: > On Saturday, 27 May 2017 at 10:29:05 UTC, Ola Fosheim Grøstad wrote: >> Hm, I would think that using __gshared would not be affected by compiler improvements, since it would turn off optimizations that assume that the variable doesn't change between reads? > > Like volatile? Volatile doesn't work. Volatile is different. Volatile means there can be side-effects from reads/writes, so the compiler cannot optimize out writes. This is for hardware registers. > __gshared has purpose to behave like old good global variable simply to provide a low level feature for a system language, if you need something else, then use the right tool. Doesn't make much sense to me. If the semantics in C is that everything is typed shared then it should also be treated as such when D interfaces with C and C like type-semantics. |
May 30, 2017 Re: std.functional.memoize : thread local or __gshared memoization? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ola Fosheim Grøstad | On Saturday, 27 May 2017 at 16:27:46 UTC, Ola Fosheim Grøstad wrote:
> If the semantics in C is that everything is typed shared then it should also be treated as such when D interfaces with C and C like type-semantics.
Then you would need to laboriously mark everything related to C as shared, which would be quite different from C workflow.
|
May 30, 2017 Re: std.functional.memoize : thread local or __gshared memoization? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Kagamin | On Tuesday, May 30, 2017 19:00:12 Kagamin via Digitalmars-d wrote:
> On Saturday, 27 May 2017 at 16:27:46 UTC, Ola Fosheim Grøstad
>
> wrote:
> > If the semantics in C is that everything is typed shared then it should also be treated as such when D interfaces with C and C like type-semantics.
>
> Then you would need to laboriously mark everything related to C as shared, which would be quite different from C workflow.
Everything is shared is C, but it's not marked as shared, so even though almost all of it is used as if it were thread-local, it isn't actually guaranteed to be so. This means that if you were being paranoid about it, you'd have to treat every C API as shared, but that is completely impractical and rarely fits what the C API actually does. In the vast majority of cases, if the C code were translated to D code, it would be translated as thread-local and be just fine. Well-behaved C code acts like D code in that it segregates code that operates on data as if it's on one thread and code that operates on data that's shared across threads, even if C doesn't have the helper attributes that D does.
So, when dealing with a C API and shared, it's a bit like dealing with @system/@trusted and C APIs. With @system/@trusted, it's up to the programmer to figure out what's safe and what isn't based on what the API does. If it's appropriately memory-safe, then it's okay to mark it as @trusted, and if there's a problem, then you know that you need to dig into the C code to fix it. If it's not memory-safe, then it needs to be marked with @system (or nothing), and the programmer needs to make sure that they use it correctly in order to make the code that uses it memory-safe.
With C APIs and shared, the programmer needs to be sure of whether it's thread-safe to treat that API call as if it's operating on thread-local data, or whether it needs to be treated as operating on shared data, and then mutexes need to be used as appropriate. Fortunately, it's usually clear, and in the vast majority of cases, treating the C function as operating on thread-local data is just fine. But it is true that you need to be a bit careful when binding to C APIs to make sure that something which isn't thread-safe is not treated as thread-local.
- Jonathan M Davis
|
Copyright © 1999-2021 by the D Language Foundation