当前位置:网站首页>Volatile instruction rearrangement and why instruction rearrangement is prohibited
Volatile instruction rearrangement and why instruction rearrangement is prohibited
2022-07-05 12:36:00 【Hua Li Hu Shao】
java Instruction rearrangement and volatile Why prohibit instruction rearrangement
Instruction reordering
What is instruction reordering
The processor optimizes the written code out of order , And guarantee that Optimized execution
Results and normal execution results ( Sequential execution results ) It's consistent .
example Write code int a=1; int b=2; But the real execution after instruction rearrangement
His order when he goes It could be int b=2 then int a =1;
Instruction rearrangement is not arbitrary rearrangement Rearrangement can But you have to By dealing with dependencies
Get the right results
example int a=1; int b=a+1; int c=2;
This situation because b Our needs depend on a So b I can't get to a front c Of
Then it doesn't matter because c Do not rely on Any of them .
To hear that The problem is coming. It's hard to rearrange instructions What's the use of eggs ?···
Why reorder instructions What is the instruction rearrangement
Instruction rearrangement is to improve the running efficiency of programs in multiprocessor environment , How to improve ?
such as Two processors process two shared variables at the same time
processor 1 Variable a++ Variable b++
processor 2 Variable a++ Variable b++
At this time, both processors execute first a++ operation To ensure data security It must be one
One by one , One by one, then there must be a processor in idle state
It can only run after another processor completes the operation of shared variables , This leads to cpu
Waste of resources .
After instruction rearrangement optimization This may happen
processor 1 Variable a++ Variable b++
processor 2 Variable b++ Variable a++
When the processor 1 operation a When processor 2 In operation b
By rearranging the execution order of instructions Avoided cpu Waste of resources
ps( Here I just give a simple example , The real situation is more complicated than this Doha haha )
volatile
volatile What is it ?
I don't know where to start , Direct words Maybe too direct will be a little mengha ha After thinking for a long time, I decided to transition from the memory model .
understand java The memory model starts with Talking about the memory model of the computer ( Don't worry, soon = = )
The memory model of a computer
Now in the computer There are several orders of magnitude differences in the computing speed between storage devices and processors ( Maximum memory read / write speed Can't keep up with the processing speed of the processor ) It's just Therefore, we have to add a layer of cache with reading and writing speed as close as possible to the processing speed of the processor As a buffer between memory and processor , Copy the data to be used to the buffer during operation After the operation Write it back to main memory , Each processor has its own independent cache , Cache based storage interaction solves the speed conflict between processor and memory , however however But it also brings higher complexity to the computer system , Because it introduces a new problem : Cache consistency (CacheCoherence).
In a multiprocessor system , Each processor has its own cache , And they share the same main memory (MainMemory).
Multiprocessor computing tasks involve a memory area Synchronization will occur in main memory It can lead to The data in each cache is inconsistent At this time, according to whom ? So every processor should abide by some protocols when accessing the cache MSI MESI MOSI… Etc., etc.
Look at the picture It should be
java Memory model in
jmm(JavaMemoryModel)
java Virtual machine defines its own memory model It is similar to the computer memory model above Mainly to shield the underlying differences between various hardware and operating systems
java The memory model specifies
1, All shared variables are stored in main memory , The variables here refer to instance variables and class variables , Does not contain local variables , Because local variables are thread private , So there's no competition .
2, Each thread also has its own working memory , Thread's working memory , Keep a copy of the variables used by the thread copied from main memory .
3, All operations of a thread on variables ( read , take ) Must be done in working memory , Variables in main memory cannot be read or written directly .
4, Different threads can not directly access the variables in the working memory of each other , The value transfer of variables between threads needs to be completed through main memory transfer
Visibility issues
What is visibility ? When a thread changes the value of a variable Other threads will immediately know , Ordinary variables cannot do this .
for example : Threads a Modified the value of ordinary variable Then write back to main memory Threads b In a thread a Read before writing back to main memory A variable's value When a thread a Write back to main memory Threads b The variable data that has been read will not change
public class MyTestThread extends Thread {
public boolean testMark=false; // Default false
public MyTestThread(){
}
@Override
public void run() {
while (true){
if(testMark){
// If testMark yes true Print
System.out.println(" My head is not made of dough !");
break;
}
}
}
}
public static void main(String[] args){
MyTestThread myTestThread=new MyTestThread();
myTestThread.start();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
// hold myTestThread Of testMark Set to true
myTestThread.testMark=true;
}
Run the main function You'll find that “ My head is not made of dough !” Never print out
Because when run Method Don't call from main memory copy The next data is mark=false When the main thread turns mark It is amended as follows true And synchronize the master and slave myTestThread The thread did not read variables from main memory again mark value therefore myTestThread In thread mark It's always been false This is the visibility of threads .
Solution : hold testMark Variable usage volatile modification
public volatile boolean testMark=false; // Default false
All right, all right Here it comes
volatile
volatile Can be said to be java One of the lightest synchronization mechanisms provided in , It has two properties
1, Ensure the visibility of variables modified by him in all threads .
2, Disable instruction reordering
First of all, the first one How does it guarantee Visibility of variables in threads Simply speaking Every time you use the value Go to main memory and re read the latest variable value Here we use the above Agreement of conformity
MESI ( To put it simply If you are interested, you can find some blogs by yourself I think it's all written But it's too wordy, I feel ··· )
Write operations : When a thread writes to a shared variable It will set the corresponding shared variable copy in other threads to invalid state .
Read operations : When a thread uses shared variables, it will first determine the state of the current copy variable If it is invalid Will want to bus send read The message reads the latest data of the variable The bus runs through all caches and main memory used by this variable The latest data read may come from main memory It may also come from other threads
In terms of code After modifying the shared variable, there will be a lock Instructions This instruction will write the thread cache to memory and Invalidate the cache in other threads ( Buffer lock )
the second Disable instruction reordering
seeing the name of a thing one thinks of its function It is to prohibit the above-mentioned instruction rearrangement The processor will not optimize the code out of order Just execute in the order of writing , After the operation variable, there will be a Memory barrier Instructions after the memory barrier cannot be reordered to the position before the memory barrier .
Why is instruction reordering prohibited Wouldn't instruction rearrangement improve operation efficiency ?
hypothesis volatile There is no command rearrangement function Variables will only ensure that the correct results can be obtained in all places that depend on the value results during the execution of the method But the execution order of this method cannot be guaranteed In the same order as the code is written This will cause problems in a multithreaded environment
A classic example ( come from In depth understanding of java virtual machine ): Explain the problem
volatile There is no command rearrangement function
public volatile boolean testMark=false; // Shared variables
Map configOptions;
char[] configText;
// Threads 1 Logic
{
// Analog read configuration information , When the reading is complete, put testMark Set to ture As a notice Other threads The configuration can be read
configOptions=new HashMap<>();
// Read profile information
configText=readConfigFile(fileName);
// Put the configuration file information into configOptions
processConfigOptions(configText,configOptions);
// The flag bit is set to ture
testMark=true;
}
// Threads 2 Logic
{
// Circular judgement testMark wait for testMark by true
while(!testMark ){
}
// Read configuration information
doSomethingWithConfig();
}
If not prohibited Command rearrangement Threads 1 in hold testMark=true; Rearranged to Load configuration information
At this point the thread 2 You'll find out immediately testMark=true; And carry on Read configuration information however Threads 1 Just execute first testMark=true; Profile loading Not yet implemented ,configOptions No data At this time, if you carry out this operation configOptions.get(“token”); You're going to report a mistake .
All right. That's it ! If there's a problem with what's written You can come up with Correction wave haha ! Thank you for your ! Here is the lively and optimistic natural and unrestrained Li
边栏推荐
- MySQL transaction
- MySQL basic operation -dql
- Solution to order timeout unpaid
- 强化学习-学习笔记3 | 策略学习
- MySQL function
- Distributed solution - completely solve website cross domain requests
- The evolution of mobile cross platform technology
- How can labels/legends be added for all chart types in chart. js (chartjs.org)?
- Detailed structure and code of inception V3
- What is digital existence? Digital transformation starts with digital existence
猜你喜欢
Average lookup length when hash table lookup fails
Four operations and derivative operations of MATLAB polynomials
Pytoch uses torchnet Classerrormeter in meter
MySQL transaction
- [email protected] (using password"/>
Solve the error 1045 of Navicat creating local connection -access denied for user [email protected] (using password
Get the variable address of structure member in C language
Principle of universal gbase high availability synchronization tool in Nanjing University
Learn the memory management of JVM 02 - memory allocation of JVM
UNIX socket advanced learning diary - advanced i/o functions
MySQL index - extended data
随机推荐
MySQL index - extended data
Migrate data from Mysql to neo4j database
PXE启动配置及原理
Learn the memory management of JVM 03 - Method area and meta space of JVM
Understand redis persistence mechanism in one article
Swift - enables textview to be highly adaptive
PXE startup configuration and principle
强化学习-学习笔记3 | 策略学习
MySQL trigger
Course design of compilation principle --- formula calculator (a simple calculator with interface developed based on QT)
Anaconda creates a virtual environment and installs pytorch
MySQL storage engine
JDBC exercise - query data encapsulated into object return & simple login demo
7月华清学习-1
GPON other manufacturers' configuration process analysis
MySQL regular expression
Redis highly available sentinel cluster
MySQL log module of InnoDB engine
Learn memory management of JVM 01 - first memory
UNIX socket advanced learning diary - advanced i/o functions