我试图准确理解什么是内存障碍.根据我目前所知,存储器屏障(例如:) mfence用于防止指令从存储器屏障之前到之后和之后重新排序.
这是使用中的内存屏障的示例:
instruction 1
instruction 2
instruction 3
mfence
instruction 4
instruction 5
instruction 6
Run Code Online (Sandbox Code Playgroud)
现在我的问题是:mfence指令只是一个标记,告诉CPU执行指令的顺序是什么?或者它是CPU实际执行的指令,就像它执行其他指令(例如:) mov.
假设我有两个线程来操纵全局变量x.每个线程(或我认为的每个核心)都有一个缓存副本x.
现在说Thread A执行以下说明:
set x to 5
some other instruction
Run Code Online (Sandbox Code Playgroud)
现在set x to 5执行时,缓存的值x将设置为5,这将导致缓存一致性协议使用新值来操作和更新其他核心的缓存x.
现在我的问题是:什么时候x实际设置5在Thread A缓存中,其他内核的缓存在some other instruction执行之前是否会更新?或者应该使用内存屏障来确保?:
set x to 5
memory barrier
some other instruction
Run Code Online (Sandbox Code Playgroud)
注意:假设指令是按顺序执行的,也假设set x to 5执行时,5会立即放入线程A的缓存中(因此指令不会放在队列中或稍后要执行的内容).
说我有以下代码:
// global variable
int i = 0;
...
EnterCriticalSection(&CriticalSection);
i = 45;
i = 24;
i = 32;
LeaveCriticalSection(&CriticalSection);
Run Code Online (Sandbox Code Playgroud)
CPU是否可以缓存变量i,并且在i修改时,缓存的副本是被修改的副本,并且在LeaveCriticalSection()调用时,缓存的值i被刷新到内存(例如,其他线程可以看到更新的值)?
根据我的理解:
编译器可以对我的代码执行任何重新排序.
临界区内的代码不会移动到临界区的外部.
现在说我有以下代码:
printf("Hi");
EnterCriticalSection(&CriticalSection);
printf("Inside the critical section");
printf("Also inside the critical section");
LeaveCriticalSection(&CriticalSection);
printf("Bye");
Run Code Online (Sandbox Code Playgroud)
现在,编译器是否会实际查找函数EnterCriticalSection(),LeaveCriticalSection()而不是将它们内部的代码移到外面?