赫伯·萨特原子武器"Why Standalone Fences are Suboptimal"
Herb Sutter Atomic Weapons "Why Standalone Fences are Suboptimal"
在他关于记忆屏障(栅栏)的演讲接近尾声时,他给出了以下例子(注意:global
是原子类型的而不是):
// thread 1 // thread 2
widget *temp = new widget();
global = temp;
global->do_something();
global->do_something_else();
后来他说我们应该有完整的围栏,如下所示:
// thread 1 // thread 2
widget *temp = new widget();
XX mb(); XXXXXXXXXXXXXXXXXXXXX
global = temp;
temp2 = global;
XX mb(); XXXXXXXXXXXXXXXX
temp2->do_something();
temp2 = global;
XX mb(); XXXXXXXXXXXXXXXX
temp2->do_something_else();
我想知道为什么在线程1中需要一个屏障?global
依赖于temp
,编译器无论如何都不会将global = temp;
移动到temp
的构造之上。我认为需要内存屏障的一个原因是,语句global=temp;
可以在new widget()
的构造过程中完成,然后线程2将看到部分构造的global
。是否可能在构建新的widget
的过程中安排对global
的分配?或者记忆障碍是由于其他原因造成的?
同样在线程2中,您不需要temp2->do_something();
之后的另一个屏障吗?与当前转换的形式一样,以下语句在执行过程中仍然可以重新排序:
temp2 = global;
XX mb(); XXXXXXXXXXXXXXXX
temp2 = global;
temp2->do_something();
XX mb(); XXXXXXXXXXXXXXXX
temp2->do_something_else();
这不是您想要的,因为现在您只在一个temp2
上调用成员函数,而不是在执行do_something_else()
之前从global
读取新值。
如果在线程2中不可能进行这样的重新排序,那么如果temp2->do_something();
不能在temp2 = global;
之前重新排序,为什么我们首先需要在线程2中设置屏障呢。
我想知道为什么在线程1中需要一个屏障?全局取决于温度编译器不会移动global=temp;高于无论如何,温度。
它与temp
内部成员的初始化有关。由于CPU缓存和重新排序,在没有内存屏障的情况下,global
可能具有新temp
的地址,但temp
指向的内存可能看起来未初始化。
至于第二个问题,显然
temp2->do_something();
temp2 = global;
不能作为重新排序
temp2 = global;
temp2->do_something();
因为它将对完全不同的对象执行某些操作!
相关文章:
- Why is UINT32_MAX + 1 = 0?
- Why (int)pow(2, 32) == -2147483648
- Visual Studio Static Linking for Standalone Exe
- Spirit X3, ascii::cntrl why disparity with std::iscntrl?
- Why is std::abs(9484282305798401ull) = 9484282305798400?
- 从"char"到"const char*"的无效转换[-fpermissive](idk why)
- C++ using std::why?
- why System.IndexOutOfRangeException
- WHy 选择挂起 => 两台 UDP 服务器(广播)
- 赫伯·萨特原子武器"Why Standalone Fences are Suboptimal"
- Why int/int = int?
- Why std::string str = {}?
- 即使有C++11/14,给出的答案仍然是"Why switch statement cannot be applied on strings?"真的吗?
- C++ Why does LLONG_MIN == -LLONG_MIN
- eclipse(stm32)Why中的项目资源管理器中,一些stderivi文件显示为灰色
- 在动态分配中,在关键字new之前使用Why(unsigned char*)
- 能够使用static_cast why消除constness
- c++Why是关于字符串的教程中使用的一组字符
- Why a[v] = v[a]?
- HeapCorruption - why?