我知道这memory_order_consume
已被弃用,但我试图了解原始设计中的逻辑以及如何[[carries_dependency]]
以及kill_dependency
应该如何工作。为此,我想要一个特定的代码示例,它会在 IBM PowerPC 或 DEC alpha 或什至具有假设编译器的假设架构上中断,该编译器在 C++11 或 C++14 中完全实现了消费语义。
我能想到的最好的例子是这样的:
int v;
std::atomic<int*> ap;
void
thread_1()
{
v = 1;
ap.store(&v, std::memory_order_release);
}
int
f(int *p [[carries_dependency]])
{
return v;
}
void
thread_2()
{
int *p;
while (!(p = ap.load(std::memory_order_consume)))
;
int v2 = f(p);
assert(*p == v2);
}
我了解此代码中的断言可能会失败。但是,如果您从中删除,断言不应该失败吗?如果是这样,为什么会这样?毕竟,您请求了 a ,那么您为什么希望其他访问能够反映获取语义呢?如果删除不会使代码正确,那么(或为所有变量设置默认值)破坏其他正确代码的示例是什么?[[carries_dependency]]
f
memory_order_consume
v
[[carries_dependency]]
[[carries_dependency]]
[[carries_dependency]]
我唯一能想到的是,这可能与寄存器溢出有关?如果一个函数将一个寄存器溢出到堆栈上,然后重新加载它,这可能会破坏依赖链。因此,[[carries_dependency]]
在某些情况下可能会使事情变得高效(说在调用此函数之前无需在调用者中发出内存屏障),但还要求被调用者在任何寄存器溢出或调用另一个函数之前发出内存屏障,这在其他情况下可能效率较低案例?不过,我在这里抓住了稻草,所以仍然很想听听懂这些东西的人的来信……