Oops: "use x and y somehow" should read "use y and z somehow" in the
example I gave. Hopefully that's not too confusing.

On Tue, Sep 25, 2018 at 11:09 PM Tom Lee <[email protected]> wrote:

> How to interpret a citation given by Cezary?: "If x and y are actions of
>> the same thread and x comes before y in program order, then hb(x, y)."
>
>
> This is a great question! Hopefully I'm not too far off-base but I think
> it comes down to effects/"visibility" and this statement hints at the kinds
> of optimization that might be legal. Assume a single thread of execution
> where reordering is in play. *Instructions* implementing the actions can
> be reordered in such a way that we perform all the work required to execute
> *actions* x and y, but until the effects of those operations "leak"
> you're still not strictly violating the hb(x, y) rule.
>
> For example, sticking to the "single thread of execution" example and
> local variables:
>
> a: x =1
> b: y = 2
> c: z = x + y * 3
> d: y = z
> e...: (use x and y somehow)
>
> We could reorder the underlying instructions such that we compute z
> directly & simply omit the assignment to x and y such that what actually
> gets executed by the CPU looks more like:
>
> a: (optimized away)
> b: (optimized away)
> c: z = 3 * 2 + 1
> d: y = z
> e: (use x and y somehow)
>
> Does it matter that we've eliminated the assignments and reordered some of
> the arithmetic? Probably not: we've changed the underlying instructions but
> as far as the *effects *are concerned we ultimately "see" hb(a,b) ->
> hb(b,c) -> hb(c,d) -> hb(d,e...) and a correct execution of our program! Of
> course, this is easier to reason about when the instructions/actions
> involved are simple. Replace simple arithmetic with method calls, volatile
> reads & writes, allocation, threads, etc. and it obviously gets a whole lot
> messier.
>
> (No doubt somebody out there can formalize what I'm trying to get across
> here, I'm sort of running on intuition. :))
>
> On Tue, Sep 25, 2018 at 10:34 PM John Hening <[email protected]> wrote:
>
>> Tom,
>>
>> Actually you right. I get it!
>>
>> Gil,
>> thanks for your note. You obviously right. If I use multithreaded
>> executor I got a lot races in a result.
>> So, does it mean that my both version of example are correct?
>>
>> How to interpret a citation given by Cezary?: "If x and y are actions of
>> the same thread and x comes before y in program order, then hb(x, y)."
>> For my eye the key is in interpreting of program order. So, if we have
>> two statements [X, Y] and order of execution does not matter because both
>> are intrathread-consistent it means that [Y,X] are in program order and
>> HB(Y,X) by a rule I cite above.
>>
>> So, If we had no Executor's (and no other) guarantee it could be
>> reordered.
>>
>>
>> W dniu środa, 26 września 2018 04:49:21 UTC+2 użytkownik Gil Tene napisał:
>>>
>>> As Tom noted, The Executor's submission happens-before promise prevents
>>> a reordering of (1) and (2) above.
>>>
>>> Note that, as written, the reason you you don't have data races between
>>> (2) and (2) is that executor is known to be a single threaded executor (and
>>> will only run one task at a time). Without that quality, you would have
>>> plenty of (2) vs. (2) races. It is not that "doers contain different
>>> objects": your code submits executions of functions using the same x member
>>> of xs to all doers, and it is only the guaranteed serialization in your
>>> chosen executor implementation that prevents x,f()s from racing on the same
>>> x...
>>>
>>> On Tuesday, September 25, 2018 at 8:52:14 AM UTC-7, John Hening wrote:
>>>>
>>>> public class Test {
>>>>     ArrayList<X> xs;
>>>>     ArrayList<Doer> doers;
>>>>     Executor executor = Executors.newSingleThreadExecutor();
>>>>
>>>>     static class Doer {
>>>>       public void does(X x){
>>>>            x.f();
>>>>     // (2)
>>>>       }
>>>>     }
>>>>
>>>>     void test() {
>>>>         for(X x : xs){
>>>>             x.f();
>>>>  // (1)
>>>>
>>>>             for(Doer d : doers) {
>>>>                 executor.execute(() -> d.does(x));
>>>>             }
>>>>         }
>>>>     }
>>>> }
>>>>
>>>>
>>>>
>>>>
>>>> For my eye, if X.f is not synchronized it is incorrect because of two
>>>> facts (and only that two facts):
>>>>
>>>> 1. Obviously, there is data race between (1) and (2). There are no more
>>>> data races here. (doers contains different objects)
>>>> 2. There is no guarantee that (1) will be executed before (2). Yes?
>>>>
>>>> If X.f would be synchronized that code will be correct because:
>>>> 1. There is no data race.
>>>> 2. There is guarantee that (1) will be executed before (2) because (1)
>>>> is a synchronization action and Executor.execute is also a synchronization
>>>> access (not specifically execute itself)
>>>>
>>>> Yes?
>>>>
>>> --
>> You received this message because you are subscribed to the Google Groups
>> "mechanical-sympathy" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> email to [email protected].
>> For more options, visit https://groups.google.com/d/optout.
>>
>
>
> --
> *Tom Lee */ http://tomlee.co / @tglee <http://twitter.com/tglee>
>
>

-- 
*Tom Lee */ http://tomlee.co / @tglee <http://twitter.com/tglee>

-- 
You received this message because you are subscribed to the Google Groups 
"mechanical-sympathy" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to