在这种情况下编译器可以按自己的意愿重新排序指令 [英] In which cases compiler can reorder instructions by its own will

查看:114
本文介绍了在这种情况下编译器可以按自己的意愿重新排序指令的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在这种情况下,编译器可以通过自己的命令重新排序指令?

In which cases compiler can reorder instructions by its own will?

例如,如果像同步原语一样涉及同步原语示例:

For example, can they be reordered in case when synchronization primitives like mutexes are involved like in the following example:

void foo()
{
  int x = 0;
  {
    std::lock_guard<std::mutex> lock(g_mutex);
    std::cout << x << std::endl;
  }
  x = 1;
}

这个代码在某些条件下打印1而不是0?

Can this code print 1 instead of 0 at some conditions?

在这样的互斥锁上调用 unlock 之后,任何共享变量都会实际被修改,所以它保证其他线程将看到更新的值这些变量而不是可能缓存的变量?

And will any shared variables be actually modified after calling unlock on such mutex so it's guaranteed that other threads will see the updated values of such variables instead of the probably-cached ones?

它是否适用于所有众所周知的同步原语,如关键部分,互斥体等?

Does it apply to all well-known synchronization primitives like critical sections, mutexes etc?

它也保证下面的代码(假设线程1将在线程2之前获取指定的互斥量)将总是打印1而不是一些缓存的值(例如,0):

Is it also guaranteed that the following code (assuming that Thread 1 will acquire the specified mutex before Thread 2) will always print 1 instead of some cached value (for example, 0):

int some_global_variable = 0;

// Thread 1
mutex.lock();
some_global_variable = 1;
mutex.unlock();

// Thread 2
mutex.lock();
std::cout << some_global_variable << std::endl;
mutex.unlock();

如果是,为什么?它在哪里说明?

If so, why? Where does it stated?

推荐答案

不,它不能。互斥体的一个独特的特点是代码重排序不交叉互斥获取或释放。

No, it can't. One of the distinct features of mutex is that code reordering does not cross mutex aquisition or release.

在旁注中,临界段不是Posix模型中的同步原语在C ++线程的东西很大程度上基于)。

On a side note, critical section is NOT a synchronization primitive in Posix model (on which C++ thread stuff is largely based). Instead, it is a logical term, meaning the piece of code which has to be protected.

EDIT

回答第二个问题。

是的,这是很好的,如果线程1获得互斥量首先打印的值将是1.原因这个显式gurantee是互斥低级代码和这个代码的硬件实现的组合。虽然没有说明,我会假设两个代码属于两个不同的功能(为了简单)。注意,在这种情况下,没有编译器优化将在播放,不管互斥量 - 有两个独立的函数,并且编译器优化是函数的本地。

Yes, it is guranteed that in case thread 1 aquires the mutex first the value printed will be 1. The reason for this explicit gurantee is a a combination of mutex low-level code and hardware implementation of this code. Although not stated, I would assume two pieces of code belong to two different functions (for simplicity). Note, that in this case no compiler optimizations will be at play regardless of mutexes - there are two independent functions, and compiler optimizations are local to the functions.

在互斥量级别上,互斥量的任何实现都将包括一个直接或间接指令,用于在互斥量获得之前和之后放置一个内存栅栏。 Thos指令将指示硬件清理它的所有缓存,因此不会使用缓存的值。

On a mutex level, any implementation of mutex would include a direct or indirect instruction to put a memory fence before and after mutex is aquired. Thos instrucion will instruct hardwre to fresh all it's caches and thus no cached value would be used.

这篇关于在这种情况下编译器可以按自己的意愿重新排序指令的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆