提升:多线程性能,重用 threads/sockets

Boost: multithread performance, reuse of threads/sockets

我将首先描述我的任务,然后在下面提出我的问题。

我正在尝试为我们的分布式 DAQ 系统实施 "one thread one connection" 方案。我在 Linux 平台上将 Boost 用于线程 (thread_group),将 ASIO 用于套接字。

我们有 320 个联网的 DAQ 模块。大约每 0.25 毫秒一次,其中大约一半会生成一个数据包(大小小于标准 MTU)并发送到 linux 服务器。每个模块都有自己的长寿命 TCP 连接到服务器上的专用端口。也就是说,服务器端 应用程序 运行s 320 个线程 320 个 tcp 同步接收器,在 1Gbe NIC 上,8 CPU 个核心

320 个线程不必对传入数据进行任何计算 - 仅接收数据、生成和添加时间戳并将数据存储在线程拥有的内存中。套接字都是同步的,因此没有传入数据的线程将被阻塞。套接字在 运行.

的时间内保持打开状态

我们的要求是线程应该以尽可能小的时间延迟读取它们各自的套接字连接。阅读了 C10K and this post 我预计每个线程每秒都能轻松处理相当于至少 1K 的 MTU 大小的数据包。

我的问题是这样的:我首先通过在服务器上触发时间同步数据来测试系统(不同套接字上的传入数据相隔不到几微秒)。当数据包的数量很少(小于10)时,我发现线程时间戳被几微秒分开。 但是,如果超过 10 个,则时间戳会分散 0.7 秒。

我的问题是:

  1. 我是否完全误解了 C10K 问题并搞砸了实施? 320与C10K相比确实显得微不足道
  2. 有什么问题的提示吗?
  3. 这真的可以重用线程 and/or 套接字吗? (我真的不知道如何在我的案例中实现重用,因此不胜感激。)

320 个线程在资源方面是一个小改动,但调度可能会带来问题。

320*0.25 = 每秒 80 个请求,这意味着至少 80 次上下文切换,因为您决定 必须 在一个线程上建立每个连接。

我只是建议:不要这样做。众所周知,每个连接的线程数无法扩展。而且它几乎总是意味着对任何共享资源的进一步锁定争用(假设所有响应都不是完全无状态的)。


Q. Having read about the C10K and this post I expected that each thread will easily process the equivalent of atleast 1K of MTU size packets every second

是的。单个线程可以轻松维持(在大多数系统上)。 但是这不再是真的,显然,如果你有数百个线程试图相同,竞争一个物理核心。

因此,为了获得最大吞吐量和低延迟,拥有比可用 (!) 物理内核更多的线程几乎没有用。


Q. Could this really be a case for reuse of threads and/or sockets? (I really dont know how to implement reuse in my case, so any explanation is appreciated.)

好消息是 Boost Asio 使得使用单个线程(或有限的线程池)来服务其服务队列中的异步任务变得非常容易。

也就是说,假设您已经使用了 *_async 版本的 ASIO API 功能。

我认为绝大多数 - 如果不是全部 - 异步 IO 的 Boost Asio 示例展示了如何 运行 仅在有限数量的线程上提供服务。