首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何避免Boost ASIO反应堆被限制在一个核心上?

如何避免Boost ASIO反应堆被限制在一个核心上?
EN

Stack Overflow用户
提问于 2011-08-14 02:39:31
回答 3查看 2.6K关注 0票数 8

戴利:有没有可能我的反应堆吞吐量有限?我怎么知道呢?io_service的实现有多昂贵和可伸缩性(跨线程)?

我有一个非常大规模的并行应用程序,它运行在一台超线程双四核至强机器上,有大量的RAM和一个快速的SSD RAID。这是使用boost::asio开发的。

这个应用程序接受来自大约1000台其他机器的连接,读取数据,解码简单的协议,并将数据混洗到使用mmap()映射的文件中。这个应用程序还使用sure (WILLNEED)预取“未来的”mmap页面,因此它不太可能在页面错误时阻塞,但为了确认,我已经尝试生成多达300个线程。

它运行在Linux kernel 2.6.32-27-generic (Ubuntu服务器x64 LTS10.04)上。Gcc版本是4.4.3,boost::asio版本是1.40 (都是现货Ubuntu LTS)。

运行vmstat、iostat和top,我看到磁盘吞吐量(以TPS和数据卷为单位)为个位数%。类似地,磁盘队列长度总是比线程数小得多,所以我不认为我有I/O限制。此外,RSS会攀升,但随后会稳定在几个at (正如预期的那样),并且vmstat没有显示分页,所以我认为我不受内存限制。CPU在0-1%的用户上是恒定的,6-7%的系统是恒定的,其余的都是空闲的。线索!一个完整的“核心”(记住超线程)是CPU的6.25%。

我知道系统正在落后,因为客户端机器在超过64kB时阻塞TCP发送,并报告事实;它们都不断报告这一事实,系统的吞吐量远远低于预期的、预期的和理论上可能的。

我的猜测是我在某种锁上争执。我使用应用程序级别的锁来保护可能会发生变化的查找表,因此我将其分成256个顶级锁/表,以打破这种依赖。然而,这似乎一点帮助都没有。

所有线程都通过一个全局io_service实例。在应用程序上运行strace表明,它将大部分时间花在处理futex调用上,我认为这与io_service反应器的基于事件的实现有关。

有没有可能我的反应堆吞吐量有限?我怎么知道呢?io_service的实现有多昂贵和可伸缩性(跨线程)?

编辑:我最初没有找到另一个线程,因为它使用了一组没有与我的线程重叠的标签:-/我的问题很可能是在boost::asio reactor的实现中使用了过多的锁定。参见C++ Socket Server - Unable to saturate CPU然而,问题仍然存在:我如何证明这一点?我怎么才能修复它呢?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-08-25 14:13:45

答案确实是,即使是最新的boost::asio也只从单个线程调用epoll文件描述符,而不是同时从多个线程进入内核。我可以在某种程度上理解为什么,因为当你使用多个线程,每个线程都可以获得相同文件描述符的通知时,对象的线程安全和生存期是非常不稳定的。当我自己编写代码(使用pthread)时,它可以工作,并且可以扩展到单个内核之外。在这一点上没有使用boost::asio --令人遗憾的是,一个设计良好且可移植的库会有这样的限制。

票数 2
EN

Stack Overflow用户

发布于 2011-10-14 04:04:54

我相信如果你使用多个io_service对象(比如每个cpu核心),每个对象都由一个线程运行,你就不会有这个问题。请参阅boost ASIO页面上的http服务器示例2。

我对服务器示例2和服务器示例3进行了各种基准测试,发现我提到的实现效果最好。

票数 2
EN

Stack Overflow用户

发布于 2015-10-31 11:11:56

在我的单线程应用程序中,我通过分析发现很大一部分处理器指令被io_service::poll()用于锁定和解锁。我使用BOOST_ASIO_DISABLE_THREADS宏禁用了锁操作。它可能对您也有意义,这取决于您的线程情况。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7052519

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档