c++ - 意外的套接字 CPU 使用率

标签 c++ multithreading performance sockets boost

我遇到了一个我不明白的性能问题。我正在处理的系统有两个看起来像这样的线程:

版本 A:

  • 线程 1:数据处理 -> 数据选择 -> 数据格式化 -> FIFO
  • 线程 2:FIFO -> 套接字

其中“选择”减少了数据,线程 1 末尾的 FIFO 是线程 2 开头的 FIFO(FIFO 实际上是 TBB 并发队列)。出于性能原因,我将线程更改为如下所示:

版本 B:

  • 线程 1:数据处理 -> 数据选择 -> FIFO
  • 线程 2:FIFO -> 数据格式化 -> 套接字

最初,这种优化被证明是成功的。线程 1 具有更高的吞吐量。我并没有过多关注 Thread 2 的性能,因为我预计 CPU 使用率会更高并且(由于数据稀疏)这不是主要问题。但是,我的一位同事要求对版本 A 和版本 B 进行性能比较。为了测试设置,我将线程 2 的套接字(boost asio tcp 套接字)写入同一个盒子(127.0.0.1)上的 iperf 实例显示最大吞吐量的目标。

为了比较这两种设置,我首先尝试强制系统以 500 Mbps 的速度从套接字中写入数据。作为性能测试的一部分,我监控了 top。我所看到的让我感到惊讶。版本 A 没有出现在“top -H”上,iperf 也没有出现(这实际上是被怀疑的)。然而,版本 B(我的“boost 版”)出现在“top -H”上,CPU 利用率约为 10%,而(奇怪的是)iperf 出现了 8%。

显然,这暗示我做错了什么。我似乎无法证明我是!我已经确认的事情:

  • 两个版本都给套接字 32k 数据 block
  • 两个版本都使用相同的 boost 库 (1.45)
  • 两者具有相同的优化设置 (-O3)
  • 两者都接收完全相同的数据,写出相同的数据,并以相同的速率写入。
  • 两者都使用相同的阻塞写入调用。
  • 我正在使用完全相同的设置 (Red Hat) 从同一个盒子进行测试
  • 线程 2 的“格式化”部分不是问题(我删除了它并重现了问题)
  • 网络上的小数据包不是问题(我正在使用 TCP_CORK,并且我已经通过 wireshark 确认 TCP 段都是 ~16k)。
  • 在套接字写入后立即休眠 1 毫秒会使套接字线程和 iperf(?!) 上的 CPU 使用率回到 0%。
  • 穷人的探查器揭示的很少(套接字线程几乎总是在休眠)。
  • Callgrind 显示很少(套接字写入几乎没有寄存器)
  • 为 netcat 切换 iperf(写入/dev/null)不会改变任何东西(实际上 netcat 的 cpu 使用率约为 20%)。

我唯一能想到的是我在套接字写入周围引入了一个更紧密的循环。但是,在 500 Mbps 时,我不希望我的进程 iperf 上的 cpu 使用率会增加吗?

我不知道为什么会这样。我和我的同事基本上没主意了。有什么想法或建议吗?在这一点上,我会很乐意尝试任何事情。

最佳答案

如果没有代码片段或实际数据量,这将很难分析。

想到的一件事:如果预先格式化的数据流明显大于格式化后的数据流,您可能会花费更多的带宽/周期来通过 FIFO(套接字)边界复制更多数据。

尝试估计或测量每个阶段的数据速率。如果“选择”输出的数据速率更高,请考虑将格式移动到边界另一侧的影响。有没有可能配置A中的select->format转换不需要copy,而配置B强加了很多copy?

...只是猜测,没有对系统有更深入的了解。

关于c++ - 意外的套接字 CPU 使用率,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5279452/

相关文章:

python - Visual Studio 2017 中缺少 io.h header

c++ - 传递字符串作为线程启动例程参数 : C++

被类函数隐藏的 C++ 友元函数?

c++ - C++ 中的字符串、整数和 float 验证

c# - picbox.BorderStyle = BorderStyle.FixedSingle | picbox.BorderStyle = BorderStyle.FixedSingle |跨线程操作无效

Java串行通信和多线程

SQL 窗口函数 - SELECT DISTINCT ORDER BY LIMIT

javascript - Phonegap + jQuery Mobile 改进

c++ - 性能:循环中的声明 VS 循环中的重新初始化

c++ - 你能将整个网页嵌入到 C++ 源代码中吗?