std :: atomic | compare_exchange_weak与compare_exchange_strong

时间:2011-02-09 12:22:41

标签: c++ stl c++11 atomic c++-standard-library

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

以下摘录摘自最新草案(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);
  

备注:弱比较和交换   那些操作可能会失败   是,离开时返回false   指向的内存内容   预计在行动之前   与对象的相同   和之后的预期相同   操作。 [注意:这是假的   失败使得能够实施   更广泛的比较和交换   机器类,例如,加载锁定   存储条件机器。一个   虚假失败的后果是   几乎所有弱者的用途   比较和交换将在一个   循环。

那么,这是什么意思?

首先,它'可能'虚假失败?!为什么会失败?他们如何定义'可能'?<​​/ p>

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

修改 这就是我在libstdc ++中发现的 - 实现(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);
}

2 个答案:

答案 0 :(得分:28)

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

  

如果发生了任何更新,即使已经恢复了load-link读取的值,store-conditional也会失败。因此,LL / SC对强于读取后跟比较和交换(CAS),如果旧值已恢复,则不会检测更新(参见ABA问题)。

     

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

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

答案 1 :(得分:11)

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

有关详细信息,请参阅例如

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.