Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/firebase/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;0x:内存排序_C++_C++11_Memory Model - Fatal编程技术网

C++ C++;0x:内存排序

C++ C++;0x:内存排序,c++,c++11,memory-model,C++,C++11,Memory Model,第1111-1112页第29.3.9节和第29.3.10节中的当前状态如下所示: // Thread 1 r1 = y.load(memory_order_relaxed); x.store(1, memory_order_relaxed); // Thread 2 r2 = x.load(memory_order_relaxed); y.store(1, memory_order_relaxed); 结果r1=r2=1是可能的,因为每个线程的操作都是放松的,并且是不相关的地址。现在我的问题

第1111-1112页第29.3.9节和第29.3.10节中的当前状态如下所示:

// Thread 1
r1 = y.load(memory_order_relaxed);
x.store(1, memory_order_relaxed);

// Thread 2
r2 = x.load(memory_order_relaxed);
y.store(1, memory_order_relaxed);
结果
r1=r2=1
是可能的,因为每个线程的操作都是放松的,并且是不相关的地址。现在我的问题是关于以下(类似)示例的可能结果:

我认为在这种情况下,结果是不可能的。如果可能,y的加载将与存储同步(因此发生在之前)。与x类似,x的加载将在存储到x之前发生。但y的加载顺序是在存储到x之前(因此也发生在存储到x之前)。这就产生了一个循环的“先发生后发生”关系,我认为这是不允许的。

如果我们花时间(或者,如果你愿意,指令序列)向下流动,就像阅读代码一样,那么我的理解是

  • 获取围栏允许其他内存访问向下移动越过围栏,但不能向上移动越过围栏
  • 释放围栏允许其他内存访问向上移动越过围栏,但不能向下移动越过围栏
换句话说,如果您有类似

acquire
// other stuff
release
然后,内存访问可能会从获取/释放对的外部移动到内部,但不会以相反的方式移动(它们也可能不会完全跳过获取/释放对)


在问题的第一个示例中,使用宽松的一致性语义,硬件可以重新排序内存访问,以便存储在加载之前进入内存系统,从而允许r1=r2=1。第二个示例中的acquire/release语义阻止了重新排序,因此r1=r2=1是不可能的。

我更改了标题,因为问题本身与投机商店无关。对于推测性存储,请参见此处的关键词Store Projection,因为结果
r1=r2=1
要求在两次读取之前对存储进行重新排序(“推测”)。你的标题太模糊了。C++0x工作文件上下文中的推测存储指的是编译器推测,请参阅我在上一篇评论中链接的问题。您的问题与硬件的重新排序有关(取决于硬件体系结构实现的共享内存一致性模型),以及C++0x如何通过发出各种内存屏障指令来提供约束这种内存重新排序的工具。因此,我觉得我提供的标题比原来的标题更合适;但是,嘿,这是你的问题,所以请随意把它改成你想要的。我不确定我是否理解你的答案。嗯,我的澄清有帮助吗?如果没有,您具体不了解什么?以我的第二个示例为例,用relaxeds替换relaxeds,acquireds。r1=r2=1可能吗?现在再次从第二个示例的初始版本重新启动,但这次将acquires替换为Released并保持发布状态。r1=r2=1可能吗?嗯,我认为在第二个例子中,为了防止r1=r2=1,每个线程只需要限制一个操作。在一个更复杂的示例中,您可能需要两者,因为在获取/发布对之间存在一些不允许“泄漏”的内容。但是,更一般地说,任何超出默认顺序一致性语义的内容最好留给正在开发高性能锁定机制或无锁算法的专家,这些机制或算法可以被普通人使用。我不是普通人:-)感谢澄清。
acquire
// other stuff
release