多线程 TCP 网络的性能

Performance of multithreaded TCP networking

我正在处理一个使用 TCP 协议的项目,该协议可能必须同时处理数百个或更多个连接。

因此,我不确定应该用什么方法收集和发送这些数据。

我想知道这里是否应用了更多线程 = 更多性能的原理。

我怀疑的原因是因为所有数据仍然必须通过网络连接提供,其中大多数设备一次只有 1 个活动。另外,我知道重复的上下文切换也会降低性能。

但是,我从其他来源了解到,多线程确实可以将网络性能扩展到一定程度,如果这是真的,为什么?

目前,我正在使用 ASIO 的 Non-Boost 变体来处理网络。

在此先感谢您的帮助。

您需要与 CPU 内核(包括超线程内核)大致相同的线程数。不多了。

每个线程处理套接字的一个子集。这样,您可以最大化 CPU 并行度,同时最小化开销。

如果您确实需要 100 多个连接 并且需要低延迟 ,您应该考虑 UDP,其中单个套接字可以从许多远程地址接收。但是你必须自己实现可靠性。尽管如此,这仍然是多人 AAA 游戏服务器通常 运行 的方式。这是有充分理由的。

多线程与单线程是一个很难的话题,我认为这完全取决于您实现的角度。
如果你在一个线程上有一个好的事件驱动系统,那么使用单线程进行低级网络 IO 可能会更好。 生成线程本身会带来性能损失,因为系统需要处理它们,当然使用额外的处理器会有所帮助,但是正如您所说,当最终进入低级别时,所有线程都需要某种同步,惩罚同样,除非您每个线程使用一个套接字。

网络上多线程(每个线程一个套接字)的一个主要缺点是大多数时候您的系统会受到 'slow loris' 攻击。 Wikipedia for slow loris Computerphile video on slow loris

因此,我认为您最好将多线程用于其他长时间等待或耗时的任务。当然你应该使用非阻塞IO。

ASIO 是 epoll/IOCP 的包装器,因此针对高性能非阻塞进行了优化 I/O。使用此设置可以在单个线程上实现数十万个同时连接。事实上,由于上​​下文切换开销,老式的“每个客户端一个线程”设置永远无法达到这种性能水平。

话虽如此,根据所使用的协议,处理网络请求和回复需要一些 CPU 时间,并且在高速率网络上,它可能会使单个 CPU 核心饱和io_service 是 运行宁。在那种情况下,可以并行化 io_service 以便完成例程可以 运行 在多个核心上。如果线程数不超过可用 CPU cores/hardware 线程数,仍然不会发生上下文切换。当 same 内核需要处理多个线程时,以及在用户模式和内核模式之间切换时(即每个系统调用两次),都会发生上下文切换。

对您的服务器进行基准测试,看看它可以在单个线程上处理多少客户端。很有可能就足够了。并行化 io_service 的代价是必须并行处理完成例程 运行,这几乎总是需要额外的同步,这意味着额外的开销。