我采取的是需要保持长寿命的连接非常大的数字(10万以上),自定义服务器。 服务器只需插座之间传递的消息,并没有做任何严重的数据处理。 消息虽小,但其中许多人都收到/发送的每一秒。 降低延迟是目标之一。 我认识到,使用多内核不会提高性能,因此,我决定通过调用运行在单个线程的服务器run_one
或poll
方法io_service
对象。 反正多线程服务器将更难实现。
可能有哪些瓶颈? 系统调用,带宽,完成队列/事件多路? 我怀疑,调度处理程序可能需要锁定(由ASIO库内部完成的)。 是否有可能在Boost.Asio的禁用甚至队列锁定(或任何其他锁定)?
编辑:相关的问题。 是否系统调用性能与多线程改进? 我的感觉是因为系统调用是原子/内核添加更多的线程不会提高速度同步。
你可能想读我的问题从几年前,我问它时,首先调查Boost.Asio的的可扩展性,同时开发了系统软件的Blue Gene / Q超级计算机 。
缩放到100K或多个连接不应该是一个问题,但你需要知道的明显的资源限制,如打开的文件描述符的最大数量。 如果你没有看过的开创性C10K纸 ,我建议阅读它。
您使用一个线程和一个实现应用程序之后io_service
,我建议研究线程调用池io_service::run()
,然后才调查钉扎的io_service
,以特定的线程和/或CPU。 有包括短耳文档所有这三个设计的多个实例,以及几个问题上所以用的更多信息。 要知道,当你引入多线程调用io_service::run()
,你可能需要实现strand
s到确保处理程序必须共享数据结构的独占访问。
使用boost :: ASIO可以大致相同的开发成本写单线程还是多线程的服务器。 你可以写单线程版本,第一个版本,然后将其转换为多线程,如果需要的话。
通常情况下,唯一的瓶颈升压:: ASIO是epoll的/ kqueue的反应器是一个互斥的工作。 所以,只有一个线程在同一时间做epoll的。 当你拥有多线程的服务器,它提供很多很多非常小的数据包这可以降低情况下的性能。 但是,海事组织它无论如何应该不仅仅是纯singlethread服务器更快。
现在,你的任务。 如果你想连接之间只传递消息 - 我认为它必须是多线程的服务器。 问题是系统调用(RECV /发送等)。 指令是很容易想到的CPU做的,但任何系统调用是不是很“轻”的操作(一切都是相对的,但是相对于其他工作在你的任务)。 所以,用单线程你会得到很大的系统调用的开销,它为什么我建议使用多线程方案。
此外,您还可以单独io_service对象 ,使之为“每个线程io_service对象”成语工作。 我想,这一定要给最好的性能,但它有缺点:如果io_service对象的人会受到太大的队列 - 其他线程不会帮助它,所以一些连接可能放缓。 在另一边,单io_service对象 - 队列溢出会导致大的锁定开销。 所有你能做的 - 做这两个变种和测量带宽/延迟。 这应该不算很难实现这两个变种。