multithreading - 什么时候无锁数据结构的性能低于互斥(互斥体)?

标签 multithreading scheduling mutex atomic lock-free

我在某处(再也找不到该页面)读到无锁数据结构“对于某些工作负载”更有效,这似乎意味着有时它们实际上速度较慢,或者在某些情况下它们的 yield 可能为零。对我来说,以大约 100 个周期的锁定指令执行原子操作听起来比进入休眠状态并等待调度程序唤醒进程备份要快得多,所以在什么情况下无锁数据结构对我来说并不明显不如老式的互斥锁更可取。如果锁在 99% 的时间内都可用并且进程不必进入休眠状态,那么互斥锁会更快吗?假设有合适的无锁数据结构可用,是否有一个好的经验法则可以知道该走哪条路?

最佳答案

实现无锁数据结构的常用方法是对不可变对象(immutable对象)进行可变引用,并让任何想要更改结构的内容获取引用,生成应用适当更改的对象的新版本,然后进行比较交换指向新对象的引用。如果 CompareExchange 有效,那就太好了。如果没有,放弃新对象,重新获取引用,然后重新开始。

如果生成新对象的成本很低并且争用级别足够低,CompareExchange 通常可以正常工作,则此方法可以很好地工作。如果存在相当大的争用,并且如果生成新对象的速度很慢,则 N 个线程同时尝试更新可能需要 N^2 时间才能完成。举个极端的例子,假设有 100 个线程在 CPU 上运行,更新需要 100 毫秒的 CPU 时间(刚好超过一个时间片),并且所有 100 个线程都尝试一次更新一个对象。在最初的十秒内,每个线程将根据原始对象生成一个新对象。其中一个线程将成功执行 CompareExchange,而其他线程都将失败。然后在接下来的 9.9 秒内,99 个线程将生成对象的新版本,之后一个将成功发布其更新,而 98 个将失败。最终结果是无锁方法将花费 505 秒的 CPU 时间来执行 100 次更新,而锁定系统可以在大约 10 秒内完成它们。

关于multithreading - 什么时候无锁数据结构的性能低于互斥(互斥体)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1585818/

相关文章:

multithreading - Goroutines 是协作调度的。这是否意味着不让出执行的 goroutine 会导致 goroutine 一个一个运行?

c# - 具有异步支持的进程同步/信令的互斥替代方案?

c++ - 如何原子地比较和递增?

linux - 从多个线程对同一个 TCP 套接字发出阻塞 write() 调用是否安全?

java - com.sun.HttpServer 套接字积压

JavaSE : First thread to call a method interrupts all other threads

python - 类似 cron 的循环任务调度程序设计

javascript - 如何在不卡住浏览器的情况下执行繁重的 JavaScript 代码?

c++ - 一旦可用就获取锁

c++ - 等待线程直到另一个线程结束 C++ linux OS