Search code examples
javaconcurrencyjava-9

What is dependency-triggered execution?


Following is a quote by Doug Lea available at this link:

Even though computation may be parallel by default at the instruction level, in Local mode, the observable results of dependency-triggered execution are always equivalent to those of purely step-wise sequential execution, whether or not any allowed optimizations actually occur. The exact relationships between statement order and execution order that maintain the associated uniprocessor semantics don't matter, and cannot even be detected (except possibly by tools such as debuggers). There are no source-level programmer controls available to alter these relationships.

What does he mean by "dependency-triggered execution"?

Some context that might help:

Plain mode applies to syntactic accesses of plain (non-volatile) object fields (as in int v = aPoint.x), as well as statics and array elements. It also applies to default VarHandle get and set access. Even though it behaves in the same way as always, its properties interact with new VarHandle modes and operations in ways best explained in terms of a quick review of relevant aspects of processor and compiler design.

Plain mode extends the otherwise unnamed "Local" mode in which all accesses are to method-local arguments and variables; for example, the code for pure expressions and functions. Plain mode maintains local precedence order for accesses, which need not match source code statement order or machine instruction order, and is not in general even a total (sequential) order.


Solution

  • I am going to try to answer, but it is how I see it. IMO, you have to take a few words back:

    ...the observable results of dependency-triggered execution.

    The way I see it, dependency triggered execution is how instructions in your code have "dependencies" between them. For example:

     int xx = ...;
     int yy = ...;
     
     int getSum(){
             
         int x = xx;
         int y = yy;
    
         return x + y;    
    
     }
    

    It does not matter if an optimizer does:

    int y = yy;
    int x = xx;
    
    return y + x;
    

    i.e. : it re-orders the instructions, or even might execute them in parallel:

    Even though computation may be parallel by default at the instruction level...

    it must always be that :

    ... in Local mode, the observable results of dependency-triggered execution are always equivalent to those of purely step-wise sequential execution.

    Whatever you observe coming from getSum is always going to be x + y, no matter how that was optimized (SSA form for instance) or even if the entire method body was executed in parallel at the processor level, for example.

    A better example that includes some dependency triggered executions can be found here; where I tried to show that even if some code has dependencies between each other, an optimizer is free to re-order the instructions as long as that is valid according to the JMM