In-depth understanding of the Java Memory Model (2)-Reorder (reprint)

Source: Internet
Author: User

Reprint Source: Http://www.infoq.com/cn/articles/java-memory-model-2

Data dependencies

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. The following three types of data dependencies are:

Name code example Description
Read after writing A = 1;b = A; After you write a variable, read the position again.
Write and write after A = 1;a = 2; After writing a variable, write the variable again.
Write after reading A = B;b = 1; After reading a variable, write the variable.

In the above three cases, the execution result of the program will be changed as long as the order of execution of the two operations is reordered.

As mentioned earlier, the compiler and the processor may reorder the operations. When the compiler and processor are reordered, data dependencies are observed, and the compiler and processor do not change the order in which the two operations exist that have data dependencies.

Note that the data dependencies described here are only for sequences of instructions executed in a single processor and for operations performed in a single thread, and 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: No matter how reordering (compilers and processors in order to improve parallelism), the execution results of (single-threaded) programs cannot be changed. Compilers, runtime, and processors must adhere to as-if-serial semantics.

To comply with as-if-serial semantics, the compiler and processor do not reorder operations that have data dependencies, because this reordering alters the execution result. However, if there is no data dependency between the actions, these operations may be reordered by the compiler and the handler. For specific instructions, see the following code example to calculate the Circle area:

Double pi  = 3.14;    adouble R   = 1.0;     bdouble area = Pi * R * r; C

The data dependencies for the above three operations are as follows:

As shown, there is a data dependency between A and C, and there is a data dependency between B and C. So in the final sequence of instructions, C cannot be reordered to the front of A and B (c to the front of a and B, the results of the program will be changed). However, there is no data dependency between A and B, and the compiler and the processor can reorder the order of execution between A and B. Is the two execution order of the program:

As-if-serial semantics protects a single-threaded program, adheres to the as-if-serial semantic compiler, and the runtime and the processor create an illusion for programmers who write single-threaded programs: single-threaded procedures are executed in the order of the program. As-if-serial semantics make it unnecessary for single-threaded programmers to worry about reordering, or to worry about memory visibility issues.

Program Order rules

According to Happens-before's program order rules, there are three happens-before relationships in the sample code that calculates the area of a circle:

    1. A Happens-before B;
    2. B Happens-before C;
    3. A Happens-before C;

The 3rd Happens-before relationship here is derived from the transitive nature of Happens-before.

Here a Happens-before B, but actually executes when B can be executed before a (see the order of execution after reordering above). As mentioned in the first chapter, if a happens-before b,jmm does not require a must be executed before B. JMM only requires that the previous operation (the result of the execution) be visible to the latter operation, and that the previous operation precedes the second operation in order. The execution result of operation A here does not need to be visible to Operation B, and the result of the reordering of operations A and B is consistent with the results of operation A and Operation B performed in Happens-before order. In this case, JMM would consider the reordering to be not illegal (not illegal), jmm allow such reordering.

In computers, software technology and hardware technology have a common goal: to develop parallelism as much as possible without changing the results of program execution. Compilers and processors follow this goal, and from the definition of happens-before we can see that JMM also follow this goal.

The effect of reordering on multithreading

Now let's see if reordering will change the execution results of multi-threaded threads. Take a look at the following sample code:

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 token used to identify whether the variable a has been written. This assumes that two threads A and B,a first execute the writer () method, and then the B thread then executes the reader () method. Thread B can see if thread a writes to the shared variable A in operation 1 when it performs Operation 4 o'clock.

The answer is: not necessarily seen.

Because operations 1 and 2 do not have data dependencies, the compiler and the processor can reorder the two operations, and similarly, operations 3 and 4 do not have data dependencies, and the compiler and the processor can reorder both operations. Let's take a look at what the effect might be when Operation 1 and Operation 2 reorder. Take a look at the following program execution timing diagram:

As shown, operation 1 and Operation 2 are reordered. When the program executes, thread a first writes the tag variable flag, and then thread B reads the variable. Because the condition is true, thread B reads the variable A. At this point, variable A is not written by thread A at all, where the semantics of multithreaded routines are broken!

※ Note: This article unifies the red imaginary arrow line to indicate the wrong reading operation, and uses the green imaginary arrow line to indicate the correct reading operation.

Let's take a look at what happens when action 3 and Operation 4 Reorder (with this reordering, you can control dependencies by the way). The following is the execution sequence diagram of the program after Operation 3 and Operation 4 reordering:

In the program, there is a control dependency between the 3 and the Operation 4. When there is a control dependency in the code, it affects the degree of parallelism that the instruction sequence executes. To do this, the compiler and processor use guessing (speculation) execution to overcome the effect of control affinity on the degree of parallelism . Taking the processor's guess execution as an example, the processor executing thread B can read and calculate the a*a in advance, and then temporarily save the results to a hardware cache called the reorder buffer (ROB). when the condition of the next operation 3 is judged to be true, the result of the calculation is written to the variable i.

As we can see, guessing execution essentially reordering operations 3 and 4. Reordering here destroys the semantics of multi-threaded threads!

In a single-threaded program, reordering of existing control-dependent operations does not alter the execution result (which is also why as-if-serial semantics allow for reordering of operations that have control dependencies), but in multithreaded programs, the execution of a control-dependent operation may change the result of a program.

In-depth understanding of the Java Memory Model (2)-Reorder (reprint)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.