我需要编写一个C ++程序,以高速率从2个不同的NIC接收udp数据包 - 每个插槽大约45MB / s(同一台计算机上每个NIC的单个插槽)。
我开始创建一个基于事件的套接字(使用WSAEventSelect),但我想知道:这种类型的套接字模型(基于事件)是否可能意味着某些性能损失? (因为事件将以高速率触发,因此操作系统可能会导致一些延迟) 如果我选择阻塞套接字,我会减少延迟吗? 是否可以说在高吞吐量时阻塞套接字可能胜过非阻塞套接字?
注意:可伸缩性不是问题,因为我们处理的插槽不超过两个。
谢谢,
A.C。
答案 0 :(得分:3)
如果你只有两个套接字,为什么不会你使用阻塞调用?它们的开销略低于任何异步套接字API,并且具有更简单的编程模型。阻塞套接字在封面下使用异步IO,但它们在事件中阻止在Windows内核中。
您应该每个插槽调高CpuCount/2
个读取器线程。虽然如果能够处理负载(取决于您的应用程序),较少的线程将表现更好。线程越少意味着缓存占用空间越小,上下文切换越少。
如果您非常关心跨套接字负载平衡,则应该使用IO完成端口,这是Windows上执行异步IO的标准且性能最佳的方式。
延迟怎么样?在您的情况下,阻塞调用将具有与“基于事件的”套接字几乎相同的延迟,因为每个套接字有多个线程在事件上排队等待接受NIC接收的下一个数据包。使用基于回调的异步IO方法,延迟会略有增加。我希望差异非常小。内核不会引入任何延迟。例如,它不会等待时钟中断来取消阻塞线程。解除锁定立即发生。