2013-10-08 151 views
3

我需要编写一个C++程序以高速率接收来自2个不同NIC的udp数据包 - 每个套接字大约45MB/s(同一台计算机上每个网卡的单个套接字)。我开始创建一个基于事件的套接字(使用WSAEventSelect),但我想知道:这种类型的套接字模型(基于事件)可能意味着一些performane惩罚? (因为事件将以高速率触发,因此操作系统可能会导致一些延迟) 如果我选择阻塞套接字,我会减少延迟吗? 是否可以说在高吞吐量情况下,阻塞套接字可能会胜过非阻塞套接字?阻塞套接字性能与非阻塞套接字

注意:可伸缩性不是问题,因为我们处理不超过两个套接字。

感谢,

交流

回答

2

如果只有两个插槽,为什么不会使用阻塞调用?它们的开销比任何异步套接字API稍少,并且具有更简单的编程模型。阻塞套接字在封面下使用异步IO,但它们在Windows内核中封锁事件。

您应该为每个套接字启动CpuCount/2读取器线程。尽管如果他们能够处理负载,线程的执行效果会更好(取决于您的应用程序)。线程越少意味着缓存占用量少,上下文切换越少。

如果您关心跨插槽负载平衡,您应该使用IO完成端口,这是Windows上执行异步IO的标准和最佳性能方式。

什么是延迟?阻塞调用与您的案例中的“基于事件”套接字具有几乎相同的延迟,因为每个套接字有多个线程在事件中等待,以接受NIC接收到的下一个数据包。使用基于回调的异步IO方法时,延迟略有增加。我预计这个差距会非常小。内核不会引入任何延迟。它不会等待时钟中断来解锁线程。解除封锁立即发生。

+2

完全正确,尽管我甚至倾向于说阻塞调用的延迟明显较少,不仅“几乎相同”,即使每个套接字只有一个单独的阻塞线程(尽管线程可能会执行其他处理接收,所以一些额外的线程是没有错误的)。当NIC以任何方式触发中断时,数据报进入接收缓冲区,并且使用阻塞API节省了排队(和非排队)APC和簿记OVERLAPPED结构的开销。 – Damon