我正在研究使用大量传入数据进行进一步处理的应用程序(组播传输stream,具体而言)的问题。
情况如下:添加多个组播stream。 每个都有它自己的接收线程从套接字接收数据,然后将其复制到环缓冲区。 它不再做了。
在大约500至600兆位,一个特定的CPU核心达到100%。 实际上,在初始化stream时,随着以太网stream量的增加,我可以看到它几乎线性地爬向负载。
套接字代码使用WSA重叠的API。 即使当我减less线程来做到这一点(即不复制到环缓冲区,这反过来将主应用程序的任何负载减less到接近于零),我都可以很容易地将这个特定的内核陷入红色。 另外有趣的是,即使我通过关联设置将其限制在4个完全不同的核心上,该负载也存在于该特定核心上。 我最后得出的结论是在操作系统或驱动程序级别上花费了一些时间。
我已经尝试在拷贝之前一次收集n个数据报(即超过1500字节的MTU),但这只会让事情变得更糟。 我也检查了我的套接字configuration正确(非阻塞,返回值都可以)。
我想知道是否有人可以告诉我有关这个问题,也许有这个问题或有一些有用的见解,如何在Windows上有效地处理这些stream量。
(我正在使用的NIC:Intel PRO PT1000)
UPDATE
我只设置了一个testing应用程序,只有一个目标:从任意数量的多播中获取传入的UDP。 我正在用Lenbuild议的IO完成端口策略来做这件事。 现在我可以很容易地从28个组播中获得1Gbit的CPU负载(毕竟现在我没有对数据包做任何处理),但是当使用更多(更小带宽)的组播时,一般在70以上,变得越来越糟糕,工作线程似乎不平衡,大多在浪费时间(等待)。
NIC中断负载现在不是限制因素(之前是这样)。
我对这个multithreadingnetworking资料很陌生。 工作线程只不过是在IO完成端口(GetQueuedCompletionStatusEx())/ INFINITE上等待,然后当stream读取完成时,我立即发出另一个循环(如果我可以在同一个stream上同时获得更多,我将采取那些没有发出新的IO事件,FILE_SKIP_COMPLETION_PORT_ON_SUCCESS)。
我拥有和CPU核心一样多的工作线程(任何事情都让事情变得更糟)。
没想到这个提出了一个新的问题 – 但是,再次,任何帮助非常感谢!
这是我的testing应用程序的来源。 (C ++) – 应该可读:-) http://pastebin.com/xWEPPbi6
用SysInternals Process Explorer工具查看你的系统,看看这个CPU正在被使用的地方,它可能被分配给“中断”,在这种情况下,它是处理NIC中断的CPU。 如果是这种情况,请查看您的网卡驱动程序,并查看是否可以启用或调整中断合并,以便NIC为相同数量的数据报生成更少的中断。
查看是否可以卸载数据报校验和计算,如果它尚未卸载到网卡,那么计算机上的CPU时间将被使用。 请注意,如果网卡无法跟上并且驱动程序不曾抛出任何数据报,那么非分页池使用可能会存在潜在的问题(请参阅此博客 )。
切换到使用GetQueuedCompletionStatusEx(),你说你正在使用“WSA重叠API”希望你的意思是I / O完成端口方法。 如果是的话,那么GetQueuedCompletionStatusEx()将允许你用较少的系统调用来读取更多的数据报。
切换到使用RIO API(请参阅此处了解Windows注册I / O网络扩展的介绍 )。 这继续了3的主题,并提供了更多的性能获取数据报到您的代码。
已更新以反映问题更新:
发出多个读取开始以获得良好的挂起读取积压。 所以,例如,有100个待处理的读取,然后开始发布新的(如果您使用“跳过完成端口”处理,但更复杂一点,但想法是建立积压。
从GQCSEx中检索多个完成,或者没有意义使用它。
当你“内联”完成时避免递归,更喜欢循环。 否则,你正在咀嚼。
有几件事要检查高UDP多播接收率。
这个信息应该允许你处理大量的多播流量。 我们有许多客户可以毫无困难地使用常规套接字和Windows server 2008 R2及更高版本这样的安排,全天获得完整的市场数据。 Windows server 2012可以更快速地处理多播流量,并且如果将RIO更快地添加到您的程序中。 如果你正在运行非常旧的服务器版本(例如Windows server 2003),那么你将无法获得良好的性能。 其中一部分与底层硬件平台的发展有关,这些平台不包括诸如消息信号中断之类的东西,这使得我们能够使用RSS获得较大的多播接收比例增益。
我希望这有帮助。
埃德布里格斯微软公司