我即将从头开始实现一个简单的服务器,意图在给定网络连接的单个端口上实现最大吞吐量(即,从客户端接受尽可能多的请求,并允许扩展到尽可能多的客户端)从理论上讲,它最多可以输入X字节/秒和Y字节/秒输出,但保持代码尽可能简单。
如何确定代码复杂性与足够吞吐量之间的最佳权衡?
例如,this page列出IOCP(AcceptEx和WSAAccept变体),然后是“重叠”,然后是“WSAPoll”,然后是“简单”,然后是“接受”,作为服务器的高到低性能SDK示例性能
这意味着iocpserverex(使用AcceptEx)比iocpserver(使用WSAAccept)更好,但并不真正提供任何证据或基准。有人比较过这两种方法吗?
论坛讨论,例如this one状态,接受“应该”更好,但同样没有证据。
对我来说,网络速度的成本多年来保持相对稳定,而更快的CPU总是越来越便宜。如果服务器代码已经达到了为给定网络连接的容量提供服务的能力,则必须有一个收益递减的地方,这并不值得进一步复杂化。
我真正希望看到的是IOCP-overlap-WSAPoll-simple-accept列表(或类似的比较,但对于UDP服务器)以及实际的性能数字,以了解有多少改进带来了添加可能更复杂的代码。什么是这些基准测试的良好来源?在实际编码之前,了解给定方法的最佳方法可能是提供足够的吞吐量吗?
答案 0 :(得分:1)
以下是我在Network Programming For Microsoft Windows中找到的比较:
答案 1 :(得分:0)
AcceptEx()
通常表现更好的一个原因是你有一个较少的线程被上下文切换到;如果没有重叠的接受,你往往会有一个专门用于循环和接受连接的线程。如果没有AcceptEx()
,则可以在IOCP线程上完成所有操作(如果您倾向于这样)。您也可以提前创建套接字,而不是让Accept创建它们,这可能有用也可能没用,和/或性能更高。这些性能改进可能只会出现在负载很重的服务器上,而且我认为很难在简单的示例中进行演示。
AcceptEx()
的服务器实际上并不比标准accept()
循环服务器复杂得多;至少一旦你已经走下IOCP路线......
了解这些示例如何执行的一种方法是自己测试它们;我在我的博客上讨论了这个here并提供了一个简单测试程序的链接,该程序可以创建数千个并发连接并以预定的速率通过它们发送数据。计算出你想要缩放的连接数,然后做出适当的决定。
另一件需要考虑的事情是,一旦理解了它,使用高性能API是否实际上更复杂。