为什么 std::atomic_compare_exchange 会更新预期值?

问题描述 投票:0回答:3

为什么

std::atomic_compare_exchange
和它的所有兄弟姐妹都会更新传递的期望值?

我想知道除了循环中给定的简单性之外是否还有任何原因,例如:是否有一个内在函数可以在一次操作中做到这一点以提高性能?

c++ multithreading c++11 atomic compare-and-swap
3个回答
9
投票

处理器必须加载当前值,以便执行操作的“比较”部分。当比较失败时,调用者需要知道新值,以重试比较交换(您几乎总是在循环中使用它),因此如果它没有返回(例如,通过修改通过引用传递的预期值)那么调用者需要执行另一个原子加载才能获取新值。这是浪费的,因为处理器已经加载了该值。当极端性能是唯一选择时,您应该只处理低级原子操作,因此在这种情况下,您不想在一个操作可以执行时执行两个操作。


2
投票

是否有一个内在函数可以在一次操作中做到这一点以提高性能

具体可以做什么?该指令必须加载当前值来进行比较,因此在不匹配时产生当前值不需要任何成本,并且几乎保证有用。


1
投票

我想知道除了循环中给定的简单性之外是否还有任何原因,例如:是否有一个内在函数可以在一次操作中做到这一点以提高性能?

是的。例如,在 x86 上,此比较和交换 (CAS) 操作将由 cmpxchg 实现,并且当 CAS 失败时,此操作会更新预期值(在

rax
中传递)。 Arm CAS看起来是一样的(虽然我实际上无法从文档中看出,需要进行组装检查)。

结果可以在 goldbolt 中看到,在 CAS 之后返回更新的期望值不需要第二次读取:我们可能只返回已经加载了实际读取值的寄存器值。

© www.soinside.com 2019 - 2024. All rights reserved.