Friday, 2 December 2016

Out of order execution - Compiler optimizations

There are two main reasons why threads have data visibility issues. First is related to compiler optimization. Second is created by cpu and caches optimizations.
Lets start with JIT optimization
Java code is compiled to bytecode and executed on JVM. To improve performance JVM will monitor execution and if method is executed specific number of times it will be optimized.

Note:
We can modify compilation threshold with:
-XX:CompileThreshold=10000 (for client 1,500)
you can use
java -XX:+UnlockDiagnosticVMOptions -XX:+PrintFlagsFinal -version
to get all your default options.

As soon as method is hot it will be compiled to native code and replaced. There are two compilers C1 and C2 and number of optimizations. In our case we will focus on inlining.

Inlining, is a manual or compiler optimization that replaces a function call site with the body of the called function

We can experience inlining effect with multi-thread execution in simple program. We will try to stop one thread, with busy loop using other thread and boolean flag.
-- --
Lack of proper synchronization is intentional. The JIT will compile our loop method and replace it with optimized version similar to:
-- --
We can use JITWatch and validate our optimized code.

You can download log from github.

The JIT optimization prevents any updates on the flag to be visible by loop thread.
If we execute the program it never terminates

java jitoptimization.JITOptimization
I'm in the loop
Flag has been changed

To fix it we can execute the code with -XX:-Inline to disable optimization.

java -XX:-Inline jitoptimization.JITOptimization
I'm in the loop
Flag has been changed
I'm outside of the loop

This is one of the examples how JIT optimization can create out of order execution and why we have to care about data visibility in our multi thread applications.

Note:
If the program is correctly synchronized, e.g. flag is volatile, compiler prevents any optimization which affects data visibility. You can validate impact of volatile on optimized code with JITWatch volatile log.

No comments:

Post a Comment