查找可能由于线程锁定而导致的性能问题(可能)

时间:2014-06-03 18:01:53

标签: c++ linux windows multithreading valgrind

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

理论上,CPU应该非常繁忙。我知道它连接的TCP / IP设备不是限制因为服务器在两台机器上运行。一个是PC,另一个是带有Arm处理器的嵌入式设备。即使嵌入式设备的CPU使用率也只有2%左右,但它的交易量却少得多 - 大约十分之一。即使我们试图尽可能快地获取数据,两个系统也只能达到2%左右。

我的猜测是一些互斥锁被锁定并且正在阻止一个线程。这是一个纯粹的猜测!系统中有一些线程具有公共数据。也许还有其他可能性,但我该怎么说?

是否有使用像valgrind / callgrind这样的工具可能会显示系统调用所花费的时间?我也可以在Windows上使用Visual Studio 2012运行它,如果那样更好。

我们可能需要尝试浏览代码或其他内容,但不确定我们是否有时间。

任何提示赞赏。

感谢。

1 个答案:

答案 0 :(得分:5)

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

这对于获取(大多数)可重现的分析结果以及详细分析执行的指令是很好的,但是Callgrind没有检测到某些类型的性能问题:

  • 等待锁的时间
  • 花费的时间(例如,简单的sleep() / usleep()来电会有效减慢您的申请速度,但不会出现在Callgrind中)
  • 等待磁盘I / O或网络I / O所花费的时间
  • 等待换出数据的时间
  • 来自CPU缓存命中/未命中的影响(您可以尝试将Cachegrind用于此特定主题)
  • 来自CPU管道停顿,分支预测失败以及现代CPU的所有其他功能的影响,这些功能可能导致相同的指令执行速度更快或更慢,具体取决于上下文

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

虽然统计分析器非常有用,因为它们提供了真实世界的#34;结果而不是简单的指令计数,它们有可能的缺点,即您不容易获得可重复的结果(每次运行结果会有所不同),并且您需要收集足够数量的样本以获得详细结果