我不太了解InitializeCriticalSectionAndSpinCount的文档: http : //msdn.microsoft.com/en-us/library/windows/desktop/ms683476 (v= vs.85).aspx
它说:“你可以通过select一个小旋转计数显着提高性能…”
然而,因为等待一个对象的速度比等待一个对象要快,那么SpinCount越高越好? 我错过了什么? 谢谢。
(我在multithreading应用程序使用的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核心服务器上进行testing时,以下是我的非正式结果:如果执行诸如testing的超快速操作并增加一个variables,则Interlocked会胜出。 第二个是CriticalSection + SpinCount,它的旋转计数较低(如16),然后是简单的旧CriticalSection。 但是,如果扫描一个数组(例如整数),Interlocked会在CriticalSection(有或没有SpinCount)之后进入第三个。 CriticalSection +高SpinCount在所有情况下都是最慢的。
Neil Weicher www.netlib.com
文件实际上说的是,我强调你删除的文字是:
您可以通过在短时间的临界区域选择小旋转计数来显着提高性能。
所以,旋转计数的选择取决于关键部分的持续时间。
你问:
然而,因为等待一个对象的速度比等待一个对象要快,那么SpinCount越高越好?
旋转比阻塞更快是不正确的。 对于长时间的关键部分,最好避免完全旋转。 如果锁定很可能不会被释放很长一段时间,那么最好的策略就是立即阻止并等待,直到获得锁定。 即使是在短暂的时间段内,持有锁的线程也可能没有被调度运行,在这种情况下,旋转显然是CPU资源的浪费。
旋转只有在旋转时很有可能获得锁定的情况下才是有益的。 即使如此,只要花费的时间少于花费的时间,上下文切换成本。
我同意“你可以通过选择一个小旋转计数来显着提高性能”这个说法。
当我测试在8核PC上使用InitializeCriticalSectionAndSpinCount的对象池类时,最好的值是小于20的值。旋转数越大,工作越慢。
这是我的这个测试结果的推论:
我不认为旋转计数应该大于数千。 旋转计数是一个忙等待。 它不仅消耗CPU的功率,而且在CPU和RAM之间消耗很多带宽,因此可能导致其他CPU和RAM之间的流量不足。