C+ 11:如何产生“伪造失败”在compare_exchange_weak上?
有没有办法可以编写一些代码来为compare_exchange的“弱”版本产生“虚假失败”?虽然相同的代码应该很好地适用于compare_exchange_strong?
我希望看到2个API的“弱”和“强”版本之间的真正区别,任何样本吗?
多谢!
Is there a way that we can write some code to produce a "spurious failures" for the "weak" version of compare_exchange? While the same code should work well for compare_exchange_strong?
I wish to see the real difference between the "weak" and "strong" version of 2 apis, any sample for it?
Thanks a lot!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您将需要一个非X86 CPU,通常是使用 load load-linked/store - 条件喜欢ARM或AARCH64(ARMV8.1之前)。 X86
锁定CMPXCHG
实现CAS_STRONG,并且当内存中的值确实匹配时,您无能为力地削弱它并可能使其失败。CAS_WEAK可以编译为单个LL/SC尝试; CAS_STRONG必须编译到LL/SC重试循环,才能在比较是错误的情况下失败,而不仅仅是来自其他线程的高速缓存线的竞争。 (如Godbolt ,对于ARMV8
ldxr
/STXR
vs. ARMV8.1cas
)有一个线程使用Cas_weak来做100 std ::原子变量的百万增加。 ( https:// preshing .com/20150402/you-can-do-do-in-kind-of-of-ratomic-read-modify-write-operation/解释了如何使用CAS Retry Loop在一个可变的,一个可变的, 重试循环。
但是,由于这是唯一的线程写作,因此CAS_STRONG将始终成功,我们不需要 另一个线程读取相同的变量,或在同一缓存线上编写其他内容。
或者也许要做
var.fetch_or(0,std :: memory_order_relaxed)
才能真正获得缓存线的所有权,但以某种方式不会影响该值。这绝对会导致虚假的LL/SC失败。完成后,100m CAS_STRONG的尝试将将变量从0增加到100000000。但是100m CAS_Weak尝试将增加到一些较低的值,而差异是故障数量。
You'll need a non-x86 CPU, typically one that uses load-linked / store-conditional like ARM or AArch64 (before ARMv8.1). x86
lock cmpxchg
implements CAS_strong, and there's nothing you can do to weaken it and make it possibly fail when the value in memory does match.CAS_weak can compile to a single LL/SC attempt; CAS_strong has to compile to an LL/SC retry loop to only fail if the compare was false, not merely from competition for the cache line from other threads. (As on Godbolt, for ARMv8
ldxr
/stxr
vs. ARMv8.1cas
)Have one thread use CAS_weak to do 100 million increments of a std::atomic variable. (https://preshing.com/20150402/you-can-do-any-kind-of-atomic-read-modify-write-operation/ explains how to use a CAS retry loop to implement any arbitrary atomic RMW operation on one variable, but since this is the only thread writing, CAS_strong will always succeed and we don't need a retry loop. My Godbolt example shows doing a single increment attempt using CAS_weak vs. CAS_strong.)
To cause spurious failures for CAS_weak but not CAS_strong, have another thread reading the same variable, or writing something else in the same cache line.
Or maybe doing something like
var.fetch_or(0, std::memory_order_relaxed)
to truly get ownership of the cache line, but in a way that wouldn't affect the value. That will definitely cause spurious LL/SC failures.When you're done, 100M CAS_strong attempts will have incremented the variable from 0 to 100000000. But 100M CAS_weak attempts will have incremented to some lower value, with the difference being the number of failures.