c++ - 查找可能是由于线程锁定(可能)引起的性能问题

标签 c++ linux windows multithreading valgrind

我花了一些时间运行 valgrind/callgrind 来分析一个使用许多线程进行大量 TCP/IP 通信的服务器。在提高性能一段时间后,我意识到在这个特定的测试场景中,进程不受 CPU 限制,所以我看到的性能“改进”没有用。

理论上CPU应该很忙。我知道它连接的 TCP/IP 设备不是限制,因为服务器在两台机器上运行。一个是 PC,另一个是带有 Arm 处理器的嵌入式设备。即使是嵌入式设备也只有大约 2% 的 CPU 使用率,但它执行的事务要少得多——大约十分之一。尽管我们试图尽快获取数据,但两个系统最多只能获取大约 2%。

我的猜测是某个互斥锁被锁定并占用了一个线程。这是一个纯粹的猜测!系统中有几个线程具有公共(public)数据。也许还有其他可能性,但我怎么知道呢?

有没有办法使用像 valgrind/callgrind 这样的工具来显示系统调用所花费的时间?如果更好的话,我还可以使用 Visual Studio 2012 在 Windows 上运行它。

我们可能不得不尝试遍历代码或进行其他操作,但不确定是否有时间。

感谢任何提示。

谢谢。

最佳答案

Callgrind 是一个很棒的分析器,但它也有一些缺点。特别是,它假设相同的指令总是在相同的时间内执行,并且假设指令计数是最重要的指标。

这对于获得(大部分)可重现的分析结果和详 segmentation 析执行了哪些指令是很好的,但是 Callgrind 无法检测到某些类型的性能问题:

  • 等待锁的时间
  • sleep 时间(例如简单的 sleep()/usleep() 调用会有效地减慢您的应用程序,但不会显示在 Callgrind 中)
  • 等待磁盘 I/O 或网络 I/O 的时间
  • 等待数据被换出所花费的时间
  • CPU 缓存命中/未命中的影响(您可以尝试使用 Cachegrind 来解决这个特定主题)
  • 受 CPU 流水线停顿、分支预测失败以及现代 CPU 的所有其他特性的影响,这些特性可能会导致同一指令的执行速度更快或更慢,具体取决于上下文

使用 statistical 可以很好地检测到这些问题(或基于样本的)分析器。例如 SysprofOProfile ,或任何类型的“穷人抽样分析器”,如所描述的那样。在https://stackoverflow.com/a/378024 . WhozCraig 提到的 VS2012 内置分析器似乎也是一个采样分析器。

虽然统计分析器非常有用,因为它们提供“真实世界”的结果而不是简单的指令计数,但它们可能存在的缺点是您无法轻易获得可重现的结果(每次运行结果都会有所不同) ,并且您需要收集足够数量的样本才能获得详细的结果。

关于c++ - 查找可能是由于线程锁定(可能)引起的性能问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24021967/

相关文章:

windows - 用于 Linux 的 Delphi 交叉编译器

c++ - 获取错误信息

c++ - fork() 的神秘 pthread 问题

windows - 使用 PowerShell 将击键发送到特定窗口

linux - 目录的 ext4 或 btrfs 中是否应该使用内容可寻址路径?

linux - lftp pget ...不打开多线程

Windows 启动时 C++ 应用程序自动运行

C++ 打破另一个函数的循环

c++ - 如果登录失败关闭 LogonUser 句柄?

linux - bash - 如何按字数将长字符串分成多个字符串