C+ 11:如何产生“伪造失败”在compare_exchange_weak上?

发布于 2025-02-10 16:35:48 字数 145 浏览 2 评论 0原文

有没有办法可以编写一些代码来为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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

街角迷惘 2025-02-17 16:35:48

您将需要一个非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.1 cas

有一个线程使用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.1 cas)

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文