![]() |
1
36
当他们说一个关键部分是“快速”的时候,他们的意思是“当一个部分还没有被另一个线程锁定时,获取它是很便宜的”。 [注意,如果 是 已经被另一个线程锁定,那么它的速度几乎不重要。]
它之所以快是因为在进入内核之前,它使用了
这个
|
![]() |
2
26
在性能工作中,很少有东西属于“始终”类别:)如果您自己使用其他原语实现类似于操作系统关键部分的东西,那么在大多数情况下,实现的几率会更慢。 回答问题的最佳方法是使用性能度量。操作系统对象的执行方式是 非常 取决于场景。例如,如果争用较低,关键部分一般被认为是“快速”的。如果锁定时间小于旋转计数时间,它们也被认为是快速的。 要确定的最重要的事情是,关键部分的争用是否是应用程序中的一阶限制因素。如果不是,那么只需使用一个关键部分normaly并处理应用程序的主要瓶颈(或瓶颈)。 如果关键部分性能是关键的,那么可以考虑以下内容。
总之,具有锁争用的调优方案可能具有挑战性(但很有趣!)工作。关注于测量应用程序的性能,并了解您的热门路径。中的xperf工具 Windows Performance Tool kit 您的朋友在吗:)我们刚刚在Microsoft Windows SDK for Windows 7和.NET Framework 3.5 SP1中发布了4.5版( ISO is here , web installer here )您可以找到xperf工具的论坛 here . v4.5完全支持Win7、Vista、Windows Server 2008-所有版本。 |
![]() |
3
4
关键部分更快,但是 InterlockedIncrement / InterlockedDecrement 是更多。请参阅此实现使用示例 LightweightLock full copy . |
![]() |
4
3
关键部分将旋转一小段时间(几毫秒),并不断检查锁是否空闲。旋转计数“超时”后,它将返回内核事件。因此,如果锁的持有者很快就退出,那么您就不必向内核代码进行昂贵的转换。 edit:在我的代码中找到了一些注释:显然,MS堆管理器使用的spin计数为4000(整数增量,而不是ms) |
![]() |
5
1
以下是一种方法: 如果没有争用,那么与互斥体进入内核模式相比,自旋锁的速度确实很快。 当存在争用时,CriticalSection比直接使用互斥体稍微贵一些(因为检测spinlock状态需要额外的工作)。 所以它可以归结为加权平均值,其中权重取决于调用模式的具体情况。也就是说,如果你没有什么争议,那么关键部分就是大胜。另一方面,如果一直存在大量的争用,那么相对于直接使用互斥体,您将支付非常小的惩罚。但是在这种情况下,通过切换到互斥模式所获得的收益是很小的,所以您最好尝试减少争用。 |
![]() |
6
1
关键部分比互斥体快,原因是关键部分不是内核对象。这是当前进程的全局内存的一部分。互斥体实际上位于内核中,创建互斥体对象需要内核切换,但在关键部分不需要。即使关键部分很快,当线程将等待状态时,在使用关键部分时也会有一个内核切换。这是因为线程调度发生在内核端。 |
![]() |
Mathias Hölzl · 对成员变量的线程安全访问 11 年前 |