Java reordering

 

        Reordering refers to a means by which the compiler and processing reorder sequences of instructions in order to optimize program performance.

data dependency

        If two operations access the same variable, and one of the two operations is a write operation, there is a data dependency between the two operations. Data dependencies are classified into the following 3 types.

name code example illustrate
read after write a=1;b=a; After writing a variable, read the location
write after write a=1;a=2; After writing a variable, write the variable again
write after read a=b;b=1; After reading a variable, write the variable
         In the above 3 cases, as long as the execution order of the two operations is reordered, the execution result of the program will be changed. The compiler and processor will respect data dependencies when reordering, and the compiler and processor will not change the execution order of two operations that have data dependencies. Data dependencies are only for instruction sequences executed in the processor and operations executed in a single thread, data dependencies between different processors and between different threads are not considered by the compiler and processor.

as-if-serial semantics

        as-if-serial semantics means that the execution result of the program cannot be changed no matter how reordered it is. The compiler, runtime, and processor must all obey as-if-serial semantics. If there are no data dependencies between operations, these operations may be reordered by the compiler and processor. Below is an example of calculating the area of ​​a circle.
double pi = 3.14;       //A
double r = 1.0;          //B
double area = pi * r;  //C
 There is a data dependency between A and C, and there is also a data dependency between B and C. So C cannot sort before A and B, but A and B have no dependencies, and the compiler can reorder the execution order between A and B.

program order rules

       According to the program sequence rules of happens-before, there are three happens-before relationships in the code for calculating the area of ​​the circle above.
1) A happens-before B
2) B happens-before C
3) A happens-before C
        

The effect of reordering on multithreading

         Whether reordering will change the execution results of multithreaded programs.
class ReorderExample{
       int a = 0;
       boolean flag = false;
       
       public void writer(){
           a = 1;            //1
           flag = true;      //2
      }

       public void reader(){
             if(flag){      //3
                 int i= a*a;//4
                 ...
              }
       }
}
        The flag variable is a flag that identifies whether variable a has been written. It is assumed here that there are two threads A and B, A first executes the writer() method, and then the B thread executes the reader() method. When thread B performs operation 4, can it see the write of thread A to the shared variable a in operation 1?
        Not necessarily visible.
         Since operation 1 and operation 2 have no data dependencies, the compiler and processor can reorder these two operations, and similarly 3 and 4 have no data dependencies, the compiler can also reorder these two operations.
         Operation 1 and operation 2 are reordered. Thread A first marks the variable flag, and then thread B reads this variable. Since the condition is true, thread B reads variable a. At this time, variable a has not been written yet. Here is a multi-threaded program. The semantics are broken.
        There is a control dependency between operation 3 and operation 4. When the code has control dependencies, it will affect the parallelism of the instruction program.
 
Thanks to the concurrent programming network ticmy for the Chinese version:
http://www.ticmy.com/?p=315
http://ifeve.com/wp-content/uploads/2014/03/JSR133%E4%B8%AD% E6%96%87%E7%89%881.pdf
          Reordering refers to a means by which the compiler and processing reorder sequences of instructions in order to optimize program performance.

        If two operations access the same variable, and one of the two operations is a write operation, there is a data dependency between the two operations. Data dependencies are classified into the following 3 types.

name code example illustrate
read after write a=1;b=a; After writing a variable, read the location
write after write a=1;a=2; After writing a variable, write the variable again
write after read a=b;b=1; After reading a variable, write the variable
         In the above 3 cases, as long as the execution order of the two operations is reordered, the execution result of the program will be changed. The compiler and processor will respect data dependencies when reordering, and the compiler and processor will not change the execution order of two operations that have data dependencies. Data dependencies are only for instruction sequences executed in the processor and operations executed in a single thread, data dependencies between different processors and between different threads are not considered by the compiler and processor.

as-if-serial semantics

        as-if-serial semantics means that the execution result of the program cannot be changed no matter how reordered it is. The compiler, runtime, and processor must all obey as-if-serial semantics. If there are no data dependencies between operations, these operations may be reordered by the compiler and processor. Below is an example of calculating the area of ​​a circle.
double pi = 3.14;       //A
double r = 1.0;          //B
double area = pi * r;  //C
 There is a data dependency between A and C, and there is also a data dependency between B and C. So C cannot sort before A and B, but A and B have no dependencies, and the compiler can reorder the execution order between A and B.

program order rules

       According to the program sequence rules of happens-before, there are three happens-before relationships in the code for calculating the area of ​​the circle above.
1) A happens-before B
2) B happens-before C
3) A happens-before C
        

The effect of reordering on multithreading

         Whether reordering will change the execution results of multithreaded programs.
class ReorderExample{
       int a = 0;
       boolean flag = false;
       
       public void writer(){
           a = 1;            //1
           flag = true;      //2
      }

       public void reader(){
             if(flag){      //3
                 int i= a*a;//4
                 ...
              }
       }
}
        The flag variable is a flag that identifies whether variable a has been written. It is assumed here that there are two threads A and B, A first executes the writer() method, and then the B thread executes the reader() method. When thread B performs operation 4, can it see the write of thread A to the shared variable a in operation 1?
        Not necessarily visible.
         Since operation 1 and operation 2 have no data dependencies, the compiler and processor can reorder these two operations, and similarly 3 and 4 have no data dependencies, the compiler can also reorder these two operations.
         Operation 1 and operation 2 are reordered. Thread A first marks the variable flag, and then thread B reads this variable. Since the condition is true, thread B reads variable a. At this time, variable a has not been written yet. Here is a multi-threaded program. The semantics are broken.
        There is a control dependency between operation 3 and operation 4. When the code has control dependencies, it will affect the parallelism of the instruction program.   JSR-133: JavaTM Memory Model and Thread Specification
JSR 133 (Java Memory Model) FAQ: Thanks for the Chinese version provided by the concurrent programming network ticmy:
http://www.ticmy.com/?p=315
http://ifeve.com /wp-content/uploads/2014/03/JSR133%E4%B8%AD%E6%96%87%E7%89%881.pdf

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326110539&siteId=291194637