阻塞套接字性能与非阻塞套接字

4
我需要编写一个C++程序来接收两个不同网卡的UDP数据包,每个套接字的速率达到高速 ——大约每个套接字每秒45MB(同一台计算机上每个网卡一个套接字)。
我开始创建一个基于事件的套接字(使用WSAEventSelect),但我想知道:这种类型的套接字模型(基于事件的)是否可能会导致某些性能损失?(因为事件将以高速率触发,因此操作系统可能会引起一些延迟。) 如果我选择阻塞套接字,会减少延迟吗? 在高吞吐量情况下,阻塞套接字是否可以胜过非阻塞套接字?
注意:可伸缩性不是问题,因为我们只处理两个套接字。
谢谢, A.C.
1个回答

3
如果你只有两个套接字,为什么不使用阻塞调用呢?它们比任何异步套接字API的开销稍微小一些,并且具有更简单的编程模型。阻塞套接字在内部使用异步IO,但它们在Windows内核上以事件方式阻塞。
对于每个套接字,你应该启动大约 CpuCount/2 个读取线程。如果能处理负载,则较少的线程将表现更好(这取决于您的应用程序)。较少的线程意味着具有较小的缓存占用和较少的上下文切换。
如果你非常关心跨套接字负载平衡,那么你可能应该使用IO完成端口,它是在Windows上执行异步IO的标准和最佳性能的方式。
那么延迟呢?在你的情况下,阻止调用将几乎与“基于事件”套接字具有相同的延迟,因为每个套接字有多个线程在等待接受NIC接收的下一个数据包。使用基于回调的异步IO方法会略微增加延迟。我预计差异非常小。内核不会引入任何延迟。例如,它不会等待时钟中断来解除线程阻塞。解除阻塞会立即发生。

3
完全正确,尽管我更倾向于说阻塞调用具有显著的低延迟,而不仅仅是“几乎相同”,即使每个套接字只有一个阻塞线程(尽管该线程可能会执行除接收之外的处理,因此多几个线程也没有错)。数据报以任何一种方式进入接收缓冲区时,网络接口控制器都会触发中断,使用阻塞API可以节省排队(和取消排队)APC和维护OVERLAPPED结构的开销。 - Damon
如果像我一样你不知道,APC代表异步过程调用,NIC代表网络接口卡。 - Elo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接