信号量与自旋锁在实践中有多贵?

时间:2013-04-25 21:47:20

标签: multithreading performance real-time semaphore

This question询问是否可以以不影响延迟的方式改进自旋锁,但使用较少的CPU时间。大量的答案提示了C ++ 11,Boost等中的高级语言概念。

我的第一个想法是使用一个简单的C信号量,因为只有当缓冲区为空或满时,海报才需要阻止。

在编写答案的过程中,我意识到我不知道这些功能在实践中的开销是多少。直观地说,它似乎应该很小,而且对我来说它从来都不是一个优化问题,但也许它与旋转锁相比是实质性的。据推测,它也取决于系统。

this question的答案表明,当锁定少于一个线程量子时,首选自旋锁,但没有给出真实世界的指示。

this question的答案提供了一个C ++中信号量实现的工作示例,它在正文中使用带有pthread_wait的自旋锁,但它不是从任何实际的语言实现中获取的。

超过here,关于互斥锁和信号量之间的速度差异的问题被一些人声称是微不足道的。其他人说信号量较慢。

this question链接的文章表明,对于互斥锁的C#lock命令在2.4GhZ机器上实际上花了50ns(所以~100个周期)。但是,目前尚不清楚C#的实现是否代表了POSIX信号量的直接C实现。

所以,问题是,信号量在实践中使用的开销是什么,并且通过扩展,我应该何时更喜欢自旋锁,如果我关心的只是延迟(即不能保持一些原因)?

1 个答案:

答案 0 :(得分:1)

我绝不是这方面的专家,所以你应该根据你的具体情况采取我的建议。

使用本质上是原子的处理器指令实现自旋锁。因此,获取和释放锁定可以非常快。保持锁定的时间越长,锁定的争用就越多,这种理想就会降低性能。因此,它最适合不经常更新的数据。 Afaik .NET(4.0+)有自己的托管自旋锁实现,可以避免过渡到非托管代码(以及后续的内核访问),这使得开销几乎无关紧要。

几乎所有其他锁定类型都基于WaitHandles(例外,在.NET-land中,是仅托管的Monitor类),除非您编写在内核空间中运行的设备驱动程序,否则性能很可能不要变化太大(因为很大一部分成本是转换到内核空间和后面)。选择最适合您应用需求的锁类型。

如果您真的非常关心它,请将一些模拟预期工作量的性能测试放在一起,并对您的首选选项进行基准测试,以了解它们如何叠加。

相关问题