c++ - 赫伯萨特原子武器 "Why Standalone Fences are Suboptimal"

标签 c++ multithreading

在他的 talk 即将结束时关于内存屏障(fences),他举了下面的例子(注意:global is not of atomic type):

// 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 .是否有可能分配给 global被安排在 build 新的中间widget ?还是其他什么原因造成的内存障碍?

同样在线程 2 中,在 temp2->do_something(); 之后不需要另一个屏障吗? ?与当前转换后的形式一样,以下语句在执行期间仍然可以重新排序:

                                                   temp2 = global;
                                                XX mb(); XXXXXXXXXXXXXXXX 

                                                   temp2 = global;
                                                   temp2->do_something();

                                                XX mb(); XXXXXXXXXXXXXXXX
                                                   temp2->do_something_else();

这不是您想要的,因为现在您只调用一个 temp2 上的成员函数。而不是从 global 中读取新值在执行 do_something_else() 之前.

如果在线程 2 中不可能进行这样的重新排序,那么如果 temp2->do_something();,为什么我们首先需要线程 2 中的屏障?无法在 temp2 = global; 之前重新订购.

最佳答案

I wonder why in thread 1 you need a barrier? global depends on temp and compiler wouldn't move global = temp; above the construction of temp anyway.

它与 temp 内部成员的初始化有关。由于 CPU 缓存和重新排序,这里没有内存屏障 global 可能有新的 temp 地址,但 temp 指向的内存可能显示为未初始化.

至于第二个问题,显然

temp2->do_something();
temp2 = global;

不能重新排序为

temp2 = global;
temp2->do_something();

因为它会在非常不同的对象上做一些事情!

关于c++ - 赫伯萨特原子武器 "Why Standalone Fences are Suboptimal",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36434392/

相关文章:

c++ - 在数字中的特定数字处查找数字

c++ - 在 C++ Win32 中哪个 Windows SDK 最适合我?

c++ - "VC++"和 "C++"有什么区别?

C++ vector 模板参数 1 无效

C 多个 pthread 调用另一个文件中的函数并将值作为全局变量存储到其中

c++ - 每 x 秒运行一次代码,无论在循环内执行多长时间

c# - 从实例方法调用静态方法线程安全吗?

java - 如果我的程序中有多个线程,每个线程在技术上是否都有自己的堆栈?每个线程都有自己的堆吗?

c++ - 从 for 循环开始线程会阻塞 UI

.net - 当我的代码没有出现在堆栈中时,如何调试此错误?