42

我不确定是我不理解还是文档没有明确制定。

以下摘自最新草案(N3126,第 29.6 节):

bool atomic_compare_exchange_weak(volatile A* object, C * expected, C desired);
bool atomic_compare_exchange_weak(A* object, C * expected, C desired);
bool atomic_compare_exchange_strong(volatile A* object, C * expected, C desired);
bool atomic_compare_exchange_strong(A* object, C * expected, C desired);
bool atomic_compare_exchange_weak_explicit(volatile A* object, C * expected, C desired, memory_order success, memory_order failure);
bool atomic_compare_exchange_weak_explicit(A* object, C * expected, C desired, memory_order success, memory_order failure);
bool atomic_compare_exchange_strong_explicit(volatile A* object, C * expected, C desired, memory_order success, memory_order failure);
bool atomic_compare_exchange_strong_explicit(A* object, C * expected, C desired, memory_order success, memory_order failure);
bool A::compare_exchange_weak(C & expected, C desired, memory_order success, memory_order failure) volatile;
bool A::compare_exchange_weak(C & expected, C desired, memory_order success, memory_order failure);
bool A::compare_exchange_strong(C & expected, C desired, memory_order success, memory_order failure) volatile;
bool A::compare_exchange_strong(C & expected, C desired, memory_order success, memory_order failure);
bool A::compare_exchange_weak(C & expected, C desired, memory_order order = memory_order_seq_cst) volatile;
bool A::compare_exchange_weak(C & expected, C desired, memory_order order = memory_order_seq_cst);
bool A::compare_exchange_strong(C & expected, C desired, memory_order order = memory_order_seq_cst) volatile;
bool A::compare_exchange_strong(C & expected, C desired, memory_order order = memory_order_seq_cst);

备注:weak compare-and-exchange操作可能会虚假失败,即返回false,而操作前expect指向的内存内容与object相同,after与expected相同操作。[注意:这种虚假故障使得能够在更广泛的机器类别上实现比较和交换,例如负载锁定存储条件机器。虚假失败的结果是几乎所有弱比较和交换的使用都将处于循环中。

那么这是什么意思?

首先,它“可能”虚假失败?!为什么会失败?他们如何定义“可能”?

其次,我仍然不知道带有“_strong”和“_weak”后缀的函数有什么区别。有人可以解释其中的区别吗?

编辑: 这就是我在 libstdc++-implementation (atomic_0.h) 中发现的:

bool compare_exchange_weak(
    __integral_type& __i1,
    __integral_type __i2,
    memory_order __m1,
    memory_order __m2
)
{
    __glibcxx_assert(__m2 != memory_order_release);
    __glibcxx_assert(__m2 != memory_order_acq_rel);
    __glibcxx_assert(__m2 <= __m1);
    return _ATOMIC_CMPEXCHNG_(this, &__i1, __i2, __m1);
}

bool compare_exchange_strong(
    __integral_type& __i1,
    __integral_type __i2,
    memory_order __m1,
    memory_order __m2
)
{
    __glibcxx_assert(__m2 != memory_order_release);
    __glibcxx_assert(__m2 != memory_order_acq_rel);
    __glibcxx_assert(__m2 <= __m1);
    return _ATOMIC_CMPEXCHNG_(this, &__i1, __i2, __m1);
}
4

2 回答 2

45

该注释提供了一个线索,指的是LL/SC架构。来自维基百科的文章:

如果发生任何更新,则保证存储条件失败,即使加载链接读取的值已经恢复。因此,LL/SC 对比读取后跟比较和交换 (CAS) 更强,如果旧值已恢复,CAS 将不会检测更新(请参阅 ABA 问题)。

如果没有对相关内存位置的并发更新,LL/SC 的实际实现并不总是成功。两个操作之间的任何异常事件,例如上下文切换、另一个加载链接,甚至(在许多平台上)另一个加载或存储操作,都会导致条件存储虚假失败。

在 LL/SC 芯片上,compare_exchange将根据 LL/SC 实现,这可能会虚假失败,因此compare_exchange_strong需要额外的开销来在失败的情况下重试。提供两者compare_exchange_strongcompare_exchange_weak允许程序员决定他们是否希望库处理虚假故障(在这种情况下他们会使用compare_exchange_strong)或者他们是否想在自己的代码中处理它(在这种情况下他们会使用compare_exchange_weak

于 2013-03-12T16:19:34.863 回答
13

它与硬件实现的共享内存一致性模型有关。对于那些实现某种宽松一致性模型(例如发布语义)的硬件架构,您上面提到的强操作可能会有很高的开销,因此专家可以使用较弱的形式来实现在那些宽松一致性上也表现良好的算法架构。

有关更多信息,请参见例如

http://www.hpl.hp.com/techreports/Compaq-DEC/WRL-95-7.pdf

http://kernel.org/pub/linux/kernel/people/paulmck/perfbook/perfbook.html中的第 12 章和附录 C

于 2011-02-09T13:48:12.527 回答