Multithreading reordering

Reordering

Means for reordering refers to a compiler and a processor program to optimize performance for reordering a sequence of instructions.

Data dependencies

If both access the same variable operation, and both operations of a write operation, then there is data dependency between the two operations.

name Code examples Explanation
Read after write a = 1; b = a; After writing a variable, read this location
After Write Write a = 1; a = 2; ; After writing a variable, write this variable
Reading writing a = b; b = 1 After reading a variable, write this variable

In the above case 3, as long as the reordering sequence of the two operations. The results of the program will change. Compiler and processor operation may be reordered, when reordering, will comply with the data dependency, and the compiler does not change the order of execution of the processor data dependency exists two operations. It said data dependency here only for the operation and the sequence of a single thread of instructions executed in a single processor execution, data dependencies between different processors and different threads can not be considered a compiler and a processor.

as-if-serial semantics

as-if-serial semantics mean: a reordering anyway, certainly we know, reordering purpose is to increase the degree of parallelism, and compiler processor, single-threaded execution result of the program will not be changed, which is to Note that the above mentioned, reordering here for a single-threaded case. Compiler, runtime and processors must comply with as-if-serial semantics. In order to comply with as-if-serial semantics, the compiler and the processor does not make the operation of reordering data dependencies, since such reordering can change the execution results. However, the absence of data dependencies between operations if these operations can be compiled and processor reordering.

as-if-serial semantics of the single-threaded programs to protect them, to comply with as-if-serial semantics compiler, runtime and processors together to create an illusion for the programmer to write single-threaded program: single-threaded programs is to order the program implemented. as-if-serial semantics of the single-threaded programmer need not worry about reordering interfere with them, do not worry about the visibility of memory.

Program sequence rules

In the computer, software technology and hardware technology have a common goal: without changing the execution result of the program's premise, as far as possible to improve the degree of parallelism. Processor and compiler compliance with this objective, by definition happens-before we can see, JMM also comply.

The impact of multi-threaded reordering

In the case of reordering, the results of the following two threads running may occur x = 0 and y = 0

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;

/**
 * @author ZerlindaLi create at 2019/5/15 11:04
 * @version 1.0.0
 * @description HappensBeforeDemo
 */
public class HappensBeforeDemo {

    int a = 0;
    int b = 0;
    int x = -1;
    int y = -1;

    public void path1() {
        a = 1;
        x = b;
    }

    public void path2() {
        b = 2;
        y = a;
    }

    public boolean test() throws InterruptedException {
        a = b = 0;
        x = y = -1;
        CyclicBarrier cy = new CyclicBarrier(2);
        Thread t1 = new Thread(() -> {
            try {
                cy.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (BrokenBarrierException e) {
                e.printStackTrace();
            }
            path1();
        });
        Thread t2 = new Thread(() -> {
            try {
                cy.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (BrokenBarrierException e) {
                e.printStackTrace();
            }
            path2();
        });

        t1.start();
        t2.start();

        t1.join();
        t2.join();

//        System.out.println("x="+x+", y="+y);
        if (x == 0 && y == 0) {
            return false;
        } else {
            return true;
        }
    }

    public static void main(String[] args) throws InterruptedException {
        for (int i = 0; i <= 300000; i++) {
            HappensBeforeDemo tt = new HappensBeforeDemo();
            boolean b = tt.test();
            if (!b) {
                System.out.println(i);
            }
        }
    }
}

We let two threads running cycle of 30 million times, there have been two times this result
Here Insert Picture Description

Guess you like

Origin blog.csdn.net/licheng989/article/details/90235866