Windows:基于事件的重叠IO与IO完成端口,实际性能

Sha*_*Cat 5 c++ windows winsock winsock2

因此,我一直在研究正在构建的服务器应用程序的套接字的重叠IO,并且不断看到有人说“从不使用hEvent”或“ IO完成端口会更快”的评论,但是没人能说为什么不要使用hEvent,也没有人在完成端口上提供更快或更快的真实数据或编号。hEvent可以WaitForMultipleObjects()更好地适合我的应用程序,因此,如果速度差异很小,我倾向于使用它,但是我不想在没有一些实际数据告诉我在此做出多大牺牲的情况下致力于这一点。我已经在Google,Google和Google上进行了搜索,除了一些StackOverflow回答说“不要使用这个”之外,找不到任何基准或文章,也无法对这两种策略进行比较。

有人可以在此处为我提供一些有关使用hEvent和完成端口之间的实际,实际差异的真实信息或数字吗?

Sha*_*Cat 6

这个答案来自 Harry Johnston 作为对这个问题的评论,通过一些搜索,我发现了一些更WaitForMultipleObjects可怕的细节。

您可以等待的最大对象数是 64。仅此一项就使得 WFMO 方法的可扩展性几乎不存在。但进一步看,我发现了这个线程:https : //groups.google.com/forum/#!topic/comp.os.ms- windows.programmer.win32/ okwnsYetF6g

在 NT 术语中,要进入等待,必须为每个对象分配一个等待块,并且每个等待块都排队到您正在等待的对象,然后交叉链接到线程。当这些对象中的任何一个收到信号时,所有这些等待块都必须出列、取消链接并重新分配回池。所有这些都发生在 DISPATCH_LEVEL 上,除了池分配和空闲之外,所有这些都发生在调度程序自旋锁持有的情况下。

(带有 fAll == TRUE 的 WFMO 甚至更昂贵。每次向任何对象发出信号时,都必须检查所有其他对象。这一切都发生了,你猜对了,发生在 DISPATCH_LEVEL 并持有调度程序自旋锁。)

调度程序级别的自旋锁可以防止整个系统中线程的抢占和时间切片,即使有多个内核也是如此。WFMO如果您正在等待超过 3 个对象(线程有 3 个预先分配的等待块,如果您等待 3 个或更少,则可以避免很多等待),这是可怕的,也是一个很好的理由,永远不要使用任何东西。

  • 调度程序自旋锁 [自 Windows 7 以来不存在](https://channel9.msdn.com/shows/Going+Deep/Arun-Kishan-Farewell-to-the-Windows-Kernel-Dispatcher-Lock/),所以担心关于调度程序自旋锁不再适用。 (6认同)
  • Windows 7 已修复。Windows Vista 仍然具有调度程序锁。 (3认同)