Tro*_*yvs 5 c++ cpu-architecture stdatomic
有没有一种方法可以让我们编写一些代码来为compare_exchange的“弱”版本产生“虚假失败”?虽然相同的代码应该可以很好地用于compare_exchange_strong?
我希望了解 2 个 api 的“弱”版本和“强”版本之间的真正区别,有任何示例吗?
多谢!
您需要一个非 x86 CPU,通常是使用加载链接/存储条件的CPU ,如 ARM 或 AArch64(ARMv8.1 之前)。x86lock cmpxchg实现了 CAS_strong,当内存中的值匹配时,您无法削弱它并使其可能失败。
CAS_weak 可以编译为单个 LL/SC 尝试;CAS_strong 必须编译为 LL/SC 重试循环,只有在比较为 false 时才会失败,而不仅仅是来自其他线程对缓存行的竞争。(与 Godbolt 一样,针对 ARMv8 ldxr/stxr与 ARMv8.1 cas)
让一个线程使用 CAS_weak 对 std::atomic 变量执行 1 亿次增量。(https://preshing.com/20150402/you-can-do-any-kind-of-atomic-read-modify-write-operation/解释了如何使用 CAS 重试循环来实现任意原子 RMW 操作变量,但由于这是唯一的线程写入,CAS_strong 将始终成功,并且我们不需要重试循环。我的 Godbolt 示例显示使用 CAS_weak 与 CAS_strong 进行单次增量尝试。)
要导致 CAS_weak 而不是 CAS_strong 出现虚假故障,请让另一个线程读取同一变量,或在同一缓存行中写入其他内容。
或者也许做一些事情,比如var.fetch_or(0, std::memory_order_relaxed)真正获得缓存线的所有权,但不会影响价值。这肯定会导致虚假的 LL/SC 故障。
完成后,100M CAS_strong 尝试会将变量从 0 增加到 100000000。但是 100M CAS_weak 尝试将增加到某个较低的值,差异在于失败次数。
| 归档时间: |
|
| 查看次数: |
314 次 |
| 最近记录: |