提升:多线程性能,重用线程/套接字



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

我正在尝试为我们的分布式DAQ系统实现"一线程一连接"方案。我在Linux平台上使用了Boost用于线程(thread_group(和ASIO用于套接字。

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

320个线程不必对传入数据进行任何计算——只需接收数据,生成和添加时间戳,并将数据存储在线程拥有的内存中。套接字都是同步的,因此没有传入数据的线程会被阻塞。套接字在运行期间保持打开状态。

我们的要求是线程应在尽可能短的时间延迟内读取各自的套接字连接。在阅读了C10K和这篇文章之后,我预计每个线程每秒将轻松处理相当于1K MTU大小的数据包

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

我的问题是:

  1. 我是否完全误解了C10K的问题,并将实施搞砸了?320与C10K相比似乎微不足道
  2. 关于出了什么问题,有什么线索吗
  3. 这真的是重用线程和/或套接字的情况吗?(在我的情况下,我真的不知道如何实现重用,所以任何解释都很感激。(

320个线程在资源方面是一个巨大的变化,但调度可能会带来问题。

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

我只是建议:不要这样做。众所周知,每个连接的线程不按比例缩放。它几乎总是意味着在任何共享资源上进一步锁定争用(假设所有响应都不是完全无状态的(。


Q阅读了C10K和这篇文章后,我预计每个线程每秒将轻松处理相当于至少1K MTU大小的数据包

是的。一个线程可以很容易地维持这种状态(在大多数系统上(但是很明显,如果有数百个线程在尝试相同的操作,争夺物理核心,那么这就不再是真的了。

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


Q这真的是重用线程和/或套接字的情况吗?(在我的情况下,我真的不知道如何实现重用,所以任何解释都很感激。(

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

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

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

  • http://www.boost.org/doc/libs/1_57_0/doc/html/boost_asio/examples.html

相关内容

  • 没有找到相关文章

最新更新