2013-04-25 39 views
2

This question询问是否可以改善自旋锁的方式不会影响等待时间,但占用更少的CPU时间。大量的答案显示了C++ 11,Boost等中的高级语言概念。信号量与自旋锁在实践中有多昂贵?

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

然而,在编写答案的过程中,我意识到我不知道这些函数的开销在实践中。直观地说,它看起来应该很小,对我来说它从来都不是一个优化问题,但是对于自旋锁来说,它可能是实质性的。据推测它也是系统依赖的。

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

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

here以上,有关互斥体和信号量之间的速度差异的问题被声明为不重要。其他人则说信号量比较慢。

一篇链接到this question的文章表明,对于互斥锁的C#锁定命令在2.4GhZ机器上的实践中花费了50ns(如此~100个周期)。然而,目前还不清楚C#的实现是否具有代表性,即POSIX信号量的直接C实现。

所以,问题是,什么是在实践中像信号使用的开销,并推而广之,我什么时候应该更喜欢一个自旋锁,如果我所关心的是延迟(即不是由于某种原因,可维护性)?

+0

有点依赖......很多东西。通常有更多的核心比就绪线程多吗?对一个被禁止的原子整数的紧密循环的空闲内存带宽有什么影响?什么是锁定跨度 - 您是否在锁定或指针/智能指针中复制大对象? – 2013-04-26 00:11:21

+0

信号量和互斥量通常会转化为慢的内核(窗口),spinlocks不会(除非你耗尽你的时间片)。有一篇非常好的研究论文报道了这篇文章(论文是锁定自由锁定的,但我找不到它!)。本文http://msdn.microsoft.com/en-us/magazine/cc163726.aspx也有一些好的一点。 – rlb 2013-04-26 04:59:23

回答

1

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

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

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

如果您真的很在意它,可以组合一些模拟预期工作负载的性能测试,然后基准您的首选选项以查看它们的堆叠方式。

+0

+1 - 对我来说听起来不错 - 在您自己的应用程序/硬件/操作系统上测试它。 – 2013-04-26 00:12:20