4

这个问题询问是否可以以不影响延迟但使用更少 CPU 时间的方式改进自旋锁。大量答案建议了 C++11、Boost 等中的高级语言概念。

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

然而,在编写答案的过程中,我意识到我不知道这些函数在实践中的开销是多少。直觉上,它似乎应该很小,而且对我来说从来都不是优化问题,但与自旋锁相比,它可能是实质性的。大概它也取决于系统。

这个问题的答案表明,当锁定少于一个线程量子时,首选自旋锁,但没有给出真实世界的指示来说明原因。

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

这里,关于互斥量和信号量之间速度差异的问题被一些人宣布为无关紧要。其他人说信号量更慢。

此问题链接的一篇文章表明,在 2.4GhZ 机器上,互斥锁的 C# 锁定命令在实践中花费 50ns(因此约 100 个周期)。但是,尚不清楚 C# 的实现是否代表 POSIX 信号量的直接 C 实现。

所以,问题是,在实践中使用信号量的开销是多少,并且通过扩展,如果我只关心延迟(即由于某种原因而不是可维护性),我什么时候应该更喜欢自旋锁?

4

1 回答 1

1

我绝不是这方面的专家,所以你应该根据你的情况对我的建议持保留态度。

自旋锁是使用本质上是原子的处理器指令实现的。因此,获取和释放锁可以非常快。持有锁的时间越长,锁的争用越多,性能就会从这个理想中下降。因此,它最适合不经常更新的数据。Afaik .NET (4.0+) 有自己的仅托管自旋锁实现,可避免转换为非托管代码(以及随后的内核访问),这使得开销几乎微不足道。

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

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

于 2013-04-25T22:49:51.913 回答