Bry*_*Fok 3 c++ multithreading cas lock-free
例如,在 intel i3、i5、i7 x86 64 位 cpu 上,CAS 是否仅保证 max 上的原子性。8 字节对象大小?
在x86 cpu上,锁定指令被添加到CAS操作中,例如。CMPXCHG,这意味着整个缓存行被锁定以供读取CPU使用,因此 std::atomic::compare_exchange_weak()不会因虚假故障原因而返回故障?
如果在 CAS 操作中使用 x86 cpu lock,如果在共享资源上使用无锁编程而不是使用 std::mutex,性能增益是多少?
例如,如果我想写一个无锁链表。我对头节点的指针进行原子加载,并将其与它进行比较 std::atomic::compare_exchange_weak()以查看是否进行了任何更改。在这种情况下,ABA问题是否适用于x86 cpu?
您在这里有几个问题:-)
根据定义,CAS 操作始终是原子的。话虽如此,支持哪些(如果有)CAS 操作取决于您的硬件,包括此类操作可以交换的最大字节数。有些CPU(例如ARM)根本不直接支持CAS。x86-64 CPU 支持 8 字节 CAS,所有现代 CPU 也通过指令支持 16 字节 CAS(通常称为双角 CAS)CMPXCHG16b。
我不确定 CAS 是否会在您提到的 CPU 上出现虚假故障(尽管我知道在某些平台上不会出现故障)。我对那些特定CPU上的缓存架构了解不够。compare_exchange_weak然而,在和 之间进行选择时,底层硬件实现是无关紧要的compare_exchange_strong:您应该使用对您正在做的事情有意义的一个 - 如果您只是编写一个典型的小型 CAS 循环(其中对虚假的额外工作),则这是一个弱交换失败可以忽略不计),否则是强交换。这也使您的代码更加可移植和健壮。
你需要测量一下。这几乎完全取决于您的应用程序正在做什么(如果您的应用程序确实因共享资源的极高争用而成为瓶颈,那么它可能会从一开始就需要较少共享的重新设计中受益)。一般来说std::mutex是“足够好”(实际上大多数时候性能相当好),但是如果在高争用情况下锁内的工作量非常小,则锁定开销确实可能超过实际工作量,并且无锁算法可以显着提高吞吐量。
ABA 绝对适用于 x86。这是由于 CAS 本身的基本性质而出现的问题,与硬件实现无关。我在这里写了一些相关内容。
我的建议是编写无锁代码时要非常小心。它非常难以测试,并且可能会工作(甚至在生产中)多年,然后才会在某些极端情况下(例如,在稍微不同的硬件上,或者在不同的工作负载下使用时等)出现错误。不要开始编写像链表这样的通用数据结构,因为在一般情况下正确处理插入和删除是一场噩梦(至少,如果您的目标是在争用情况下保持高性能,那么这是一个噩梦)通常是因为这就是您首先编写无锁数据结构的原因)。相反,找出您的特定应用程序逻辑所需的确切最少操作,并仅实现这些操作。只添加无锁链表的编写相当简单;由于 ABA,结合去除头部或尾部的能力要复杂得多。
| 归档时间: |
|
| 查看次数: |
2524 次 |
| 最近记录: |