我不太了解InitializeCriticalSectionAndSpinCount的文档: http://msdn.microsoft.com/en-us/library/windows/desktop/ms683476(v=vs.85).aspx
它说"你可以通过选择一个小的旋转计数来显着提高性能......"
但是,由于等待微调器比等待对象更快,因此让SpinCount尽可能高是否有意义?我错过了什么?感谢。
(我在多线程应用程序使用的C DLL中使用它)
这是关键部分的代码,由大量线程不断调用:
int g_slots[256] = {0};
...
slot = 256;
EnterCriticalSection(&g_LockHandle);
while (slot-- > 0)
{
if (g_slots[slot] == 0)
{
g_slots[slot] = spid;
break;
}
}
LeaveCriticalSection(&g_LockHandle);
后续评论:
对于任何感兴趣的人,这是我在运行Windows 2008 R2的4核服务器上进行测试时的非正式结果:如果进行超快速操作(如测试和增加单个变量),Interlocked将获胜。遥远的第二个是具有低旋转计数(例如,16)的CriticalSection + SpinCount,然后是普通的CriticalSection。但是,如果扫描一个数组(例如整数),Interlocked在CriticalSection(带或不带SpinCount)之后排在第三位。 CriticalSection +高SpinCount在所有情况下都是最慢的。
Neil Weicher www.netlib.com
答案 0 :(得分:2)
文档实际上说的是,我强调您删除的文本是:
您可以通过为短期的关键部分选择小的旋转计数来显着提高性能。
因此,旋转计数的选择非常关键地取决于临界区的持续时间。
你问:
但是,因为等待微调器比等待对象更快,所以让SpinCount尽可能高是否有意义?
旋转比阻塞更快是不正确的。对于长时间的关键部分,最好完全避免旋转。如果锁定很可能不会在很长一段时间内释放,那么最好的策略是立即阻止并等到你可以获得锁定。即使是持续时间较短的部分,也可能没有安排持有锁的线程运行,在这种情况下,旋转显然会浪费CPU资源。
旋转只有在旋转时可以获得锁定的可能性很大时才有用。即便如此,只有花费的时间少于产生的时间,上下文切换成本。
答案 1 :(得分:1)
我同意声明"您可以通过选择小的旋转计数来显着提高性能"本身。
当我测试在8核PC上使用InitializeCriticalSectionAndSpinCount的对象池类时,最佳值小于20.旋转计数越大,它的工作速度越慢。
这些是我对此测试结果的推论:
我不认为旋转计数应该大于数千。旋转计数是一个繁忙的等待。它不仅消耗CPU功率,而且在CPU和RAM之间消耗大量带宽,因此可能导致其他CPU和RAM之间的流量不足。