提升Asio单线程性能

我正在实现自定义服务器,需要保持非常大的数量(100K或更多)的长期连接。 服务器只是在套接字之间传递消息,并没有做任何严肃的数据处理。 消息很小,但是其中许多消息都是每秒收到/发送的。 减less延迟是目标之一。 我意识到使用多核并不会提高性能,因此我决定通过调用io_service对象的run_onepoll方法在单个线程中运行服务器。 无论如何,multithreading服务器将更难实施。

什么是可能的瓶颈? 系统调用,带宽,完成队列/事件解复用? 我怀疑调度处理程序可能需要locking(这是由asio库内部完成)。 是否有可能禁用boost.asio甚至队列locking(或任何其他locking)?

编辑:相关的问题。 multithreading的系统调用性能是否会提高? 我的感觉是,因为系统调用是由内核primefaces/同步添加更多的线程不会提高速度。

Solutions Collecting From Web of "提升Asio单线程性能"

你可能想要阅读我几年前的问题,在开发Blue Gene / Q超级计算机的系统软件的时候,我首先调查了Boost.Asio的可扩展性。

缩放到100k或更多的连接应该不成问题,但您需要了解明显的资源限制,例如打开的文件描述符的最大数目。 如果您还没有阅读开创性的C10K论文 ,我建议您阅读。

在使用单线程和单个io_service实现应用程序之后,我建议调查调用io_service::run()的线程池,然后调查将io_service固定到特定的线程和/或cpu。 Asio文档中包含了所有这三种设计的多个示例,以及关于SO的几个问题以及更多信息。 请注意,当您引入多个线程调用io_service::run()您可能需要实现strand以确保处理程序具有对共享数据结构的独占访问权限。

使用boost :: asio,你可以编写单线程或者多线程的服务器,大约花费相同的开发成本。 您可以将单线程版本编写为第一个版本,然后根据需要将其转换为多线程。

通常,boost :: asio的瓶颈只是epoll / kqueue反应器在互斥体中工作。 所以,只有一个线程同时在做epoll。 这可以降低性能,当你有多线程服务器,它服务很多很多很小的数据包。 但是,反正它应该比简单的单线程服务器更快。

现在关于你的任务。 如果你只想在连接之间传递消息 – 我认为它必须是多线程服务器。 问题是系统调用(recv /发送等)。 一个指令很容易被认为是为CPU做的,但是任何系统调用都不是很“轻”的操作(一切都是相对的,但相对于你的任务中的其他任务)。 所以,单线程你会得到很大的系统调用开销,为什么我建议使用多线程方案。

此外,你可以分开io_service,并使其作为“每线程io_service”成语。 我认为这必须提供最好的性能,但是它有一个缺点:如果io_service中的一个会得到太大的队列 – 其他线程不会帮助它,所以一些连接可能会减慢。 另一方面,单个io_service – 队列溢出会导致很大的锁定开销。 所有你能做的 – 做这两个变种,并衡量带宽/延迟。 实现这两个变体应该不是太困难。