c - InitializeCriticalSectionAndSpinCount 最优 SpinCount(用户模式)

标签 c windows synchronization critical-section

我不太理解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 在所有情况下都是最慢的。

尼尔·韦彻 www.netlib.com

最佳答案

文档实际上所说的内容(我强调的是您删除的文本)是:

You can improve performance significantly by choosing a small spin count for a critical section of short duration.

因此,旋转计数的选择很大程度上取决于关键部分的持续时间。

你问:

However, since waiting on a spinner is faster than waiting for an object, doesn't it make sense to have the SpinCount as high as possible?

旋转比阻塞更快的说法根本不正确。对于持续时间较长的关键部分,最好完全避免旋转。如果锁可能在很长一段时间内不会被释放,那么最好的策略是立即阻塞并等待,直到可以获得锁。即使对于持续时间很短的部分,持有锁的线程也有可能没有被调度运行,在这种情况下,自旋显然会浪费 CPU 资源。

只有当旋转时很有可能获得锁时,旋转才有用。即便如此,只有当旋转所花费的时间少于屈服所花费的时间时,上下文切换才会产生成本。

关于c - InitializeCriticalSectionAndSpinCount 最优 SpinCount(用户模式),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25232164/

相关文章:

无法通过套接字 C 发送文件

windows - mftraining 给出警告 : no protos/configs for F in CreateIntTemplates()

c# - 在哪里安全地存储来自 Windows 服务的数据?

java - 查询一组资源的高效同步

c - 在命令完成之前,C 中的 popen 会阻塞吗?

c++ - C语言的Windows UIAutomatin

windows - 在 Windows 8 上开发应用程序的最低硬件和软件要求?

c - 如何等待其他线程初始化并在之后正确清理?

.net - 始终保持多个数据库同步

c - 使用 scanf 定义 malloc 数组大小并初始化