Thread overview | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
June 18, 2019 Very limited shared promotion | ||||
---|---|---|---|---|
| ||||
Is this valid? int x; void fun(scope ref shared(int) x) { ... } fun(x); // implicit promotion to shared in this case This appears to promote a thread-local to shared. The problem with such promotion is that it's not valid that a thread-local AND a shared reference to the same thing can exist at the same time. With scope, we can guarantee that the reference doesn't escape the callee. Since the argument is local to the calling thread, and since the calling thread can not be running other code at the same time as the call is executing, there is no way for any code to execute with a thread-local assumption while the callee makes shared assumptions. I think this might be safe? |
June 18, 2019 Re: Very limited shared promotion | ||||
---|---|---|---|---|
| ||||
Posted in reply to Manu | On Monday, 17 June 2019 at 23:46:44 UTC, Manu wrote:
> Is this valid?
>
> int x;
> void fun(scope ref shared(int) x) { ... }
> fun(x); // implicit promotion to shared in this case
>
> This appears to promote a thread-local to shared. The problem with such promotion is that it's not valid that a thread-local AND a shared reference to the same thing can exist at the same time.
>
> With scope, we can guarantee that the reference doesn't escape the callee.
> Since the argument is local to the calling thread, and since the
> calling thread can not be running other code at the same time as the
> call is executing, there is no way for any code to execute with a
> thread-local assumption while the callee makes shared assumptions.
>
> I think this might be safe?
Can `fun` execute a call to another nested function that accesses `x` unshared?
|
June 18, 2019 Re: Very limited shared promotion | ||||
---|---|---|---|---|
| ||||
Posted in reply to FeepingCreature | On Tue, Jun 18, 2019 at 3:05 PM FeepingCreature via Digitalmars-d <digitalmars-d@puremagic.com> wrote:
>
> On Monday, 17 June 2019 at 23:46:44 UTC, Manu wrote:
> > Is this valid?
> >
> > int x;
> > void fun(scope ref shared(int) x) { ... }
> > fun(x); // implicit promotion to shared in this case
> >
> > This appears to promote a thread-local to shared. The problem with such promotion is that it's not valid that a thread-local AND a shared reference to the same thing can exist at the same time.
> >
> > With scope, we can guarantee that the reference doesn't escape
> > the callee.
> > Since the argument is local to the calling thread, and since the
> > calling thread can not be running other code at the same time
> > as the
> > call is executing, there is no way for any code to execute with
> > a
> > thread-local assumption while the callee makes shared
> > assumptions.
> >
> > I think this might be safe?
>
> Can `fun` execute a call to another nested function that accesses `x` unshared?
Well, under my proposal, if the capture were actually qualified, it wouldn't be possible to call another local function with a lesser-qualified capture; so that's another +1 for qualifying the capture! ;)
|
June 18, 2019 Re: Very limited shared promotion | ||||
---|---|---|---|---|
| ||||
Posted in reply to Manu | On 6/17/19 7:46 PM, Manu wrote:
> Is this valid?
>
> int x;
> void fun(scope ref shared(int) x) { ... }
> fun(x); // implicit promotion to shared in this case
>
> This appears to promote a thread-local to shared. The problem with
> such promotion is that it's not valid that a thread-local AND a shared
> reference to the same thing can exist at the same time.
>
> With scope, we can guarantee that the reference doesn't escape the callee.
> Since the argument is local to the calling thread, and since the
> calling thread can not be running other code at the same time as the
> call is executing, there is no way for any code to execute with a
> thread-local assumption while the callee makes shared assumptions.
>
> I think this might be safe?
>
Seems like it would be safe, but what is the use case for it? If you have a scope shared, which can't actually get shared with anything else, what does it buy you?
-Steve
|
June 18, 2019 Re: Very limited shared promotion | ||||
---|---|---|---|---|
| ||||
Posted in reply to Manu | On 18.06.19 14:00, Manu wrote:
> On Tue, Jun 18, 2019 at 3:05 PM FeepingCreature via Digitalmars-d
> <digitalmars-d@puremagic.com> wrote:
>>
>> On Monday, 17 June 2019 at 23:46:44 UTC, Manu wrote:
>>> Is this valid?
>>>
>>> int x;
>>> void fun(scope ref shared(int) x) { ... }
>>> fun(x); // implicit promotion to shared in this case
>>>
>>> This appears to promote a thread-local to shared. The problem
>>> with such promotion is that it's not valid that a thread-local
>>> AND a shared reference to the same thing can exist at the same
>>> time.
>>>
>>> With scope, we can guarantee that the reference doesn't escape
>>> the callee.
>>> Since the argument is local to the calling thread, and since the
>>> calling thread can not be running other code at the same time
>>> as the
>>> call is executing, there is no way for any code to execute with
>>> a
>>> thread-local assumption while the callee makes shared
>>> assumptions.
>>>
>>> I think this might be safe?
>>
>> Can `fun` execute a call to another nested function that accesses
>> `x` unshared?
>
> Well, under my proposal, if the capture were actually qualified, it
> wouldn't be possible to call another local function with a
> lesser-qualified capture; so that's another +1 for qualifying the
> capture! ;)
>
Bullshit.
|
June 18, 2019 Re: Very limited shared promotion | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | On 18.06.19 15:29, Steven Schveighoffer wrote: > On 6/17/19 7:46 PM, Manu wrote: >> Is this valid? >> >> int x; >> void fun(scope ref shared(int) x) { ... } >> fun(x); // implicit promotion to shared in this case >> >> This appears to promote a thread-local to shared. The problem with >> such promotion is that it's not valid that a thread-local AND a shared >> reference to the same thing can exist at the same time. >> >> With scope, we can guarantee that the reference doesn't escape the callee. >> Since the argument is local to the calling thread, and since the >> calling thread can not be running other code at the same time as the >> call is executing, there is no way for any code to execute with a >> thread-local assumption while the callee makes shared assumptions. >> >> I think this might be safe? >> > > Seems like it would be safe, but what is the use case for it? If you have a scope shared, which can't actually get shared with anything else, what does it buy you? > > -Steve He would write @system code that leaks the reference to other threads temporarily, but ensures those references disappear once the parallel part of the computation has finished. His use case is @safe parallel foreach without having to explicitly qualify the variables in the outer scope as `shared`: void sum(){ // note: just to illustrate the concept int result=0; foreach(i;iota(1000).parallel){ static assert(typeof(result)==shared(int)); result.atomic!"+="(i); } static assert(typeof(result)==int); return result; } |
June 18, 2019 Re: Very limited shared promotion | ||||
---|---|---|---|---|
| ||||
Posted in reply to Timon Gehr | On 18.06.19 16:13, Timon Gehr wrote:
>
> int sum(){ // note: just to illustrate the concept
> int result=0;
> foreach(i;iota(1000).parallel){
> static assert(typeof(result)==shared(int));
> result.atomic!"+="(i);
> }
> static assert(typeof(result)==int);
> return result;
> }
Return type should have been int, of course...
|
June 18, 2019 Re: Very limited shared promotion | ||||
---|---|---|---|---|
| ||||
Posted in reply to Timon Gehr | On 18.06.19 16:14, Timon Gehr wrote:
> On 18.06.19 16:13, Timon Gehr wrote:
>>
>> int sum(){ // note: just to illustrate the concept
>> int result=0;
>> foreach(i;iota(1000).parallel){
>> static assert(is(typeof(result)==shared(int)));
>> result.atomic!"+="(i);
>> }
>> static assert(is(typeof(result)==int));
>> return result;
>> }
>
> Return type should have been int, of course...
And there should have been is expressions. Getting tired from pushing back against all the nonsense. Just note that if you can make the above work with useless qualified capturing, you can do so with useful qualified capturing and this is so blatantly obvious that it causes me physical pain that Manu honestly does not see it.
|
June 18, 2019 Re: Very limited shared promotion | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | On 6/18/2019 6:29 AM, Steven Schveighoffer wrote:
> Seems like it would be safe,
When dealing with concurrency, that's like throwing a bunch of chemicals into a vat and saying it seems safe to drink :-)
Just remember that doubled checked locking fooled a lot of very smart people for many years. I got snookered by it, too.
Not sure where I read about it recently, but some expert had come up with a lock free algorithm, and the bug was only discovered a couple years later.
Unless you are really, really good at concurrency, it's best to stick with atomics and locks, every time.
|
June 18, 2019 Re: Very limited shared promotion | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | On 6/18/19 4:05 PM, Walter Bright wrote:
> On 6/18/2019 6:29 AM, Steven Schveighoffer wrote:
>> Seems like it would be safe,
>
> When dealing with concurrency, that's like throwing a bunch of chemicals into a vat and saying it seems safe to drink :-)
Nope, what I wrote has nothing to do with that. I sense that you're not grasping that sending in unshared data to a place where it can't possibly be shared means it's probably safe to do.
Why you would want to do this, I'm not sure.
-Steve
|
Copyright © 1999-2021 by the D Language Foundation