为什么我的代码在编译用于分析(-pg)时使用多个线程比使用单个线程运行得慢?

时间:2010-05-21 06:33:29

标签: linux performance multithreading gcc gprof

我正在写一个光线追踪器。

最近,我在程序中添加了线程,以利用i5四核上的其他内核。

在一个奇怪的事件发生时,应用程序的调试版本现在运行得更慢,但优化的构建运行速度比我添加线程之前更快。

我将“-g -pg”标志传递给gcc用于调试版本,并将“-O3”标志传递给优化版本。

主机系统:Ubuntu Linux 10.4 AMD64。

我知道调试符号会给程序带来很大的开销,但始终保持相对性能。即在调试和优化构建中,更快的算法总是运行得更快。

知道为什么我会看到这种行为吗?

调试版本使用“-g3 -pg”编译。带有“-O3”的优化版本。

Optimized no threading:        0m4.864s
Optimized threading:           0m2.075s

Debug no threading:            0m30.351s
Debug threading:               0m39.860s
Debug threading after "strip": 0m39.767s

Debug no threading (no-pg):    0m10.428s
Debug threading (no-pg):       0m4.045s

这使我确信“-g3”不应该归咎于奇怪的性能增量,但它更像是“-pg”开关。 “-pg”选项可能会添加某种锁定机制来测量线程性能。

由于“-pg”在线程应用程序上都被破坏了,我只是删除它。

4 个答案:

答案 0 :(得分:8)

没有-pg标志你会得到什么?这不是调试符号(不影响代码生成),而是用于分析(这样做)。

在多线程进程中进行概要分析需要额外的锁定,从而减慢多线程版本的速度,甚至达到使其比非多线程版本慢的程度时,这是非常合理的。

答案 1 :(得分:2)

你在谈论两件不同的事情。调试符号和编译器优化。如果您使用编译器必须提供的最强优化设置,则会丢失在调试中有用的符号。

由于调试符号,您的应用程序运行速度不慢,由于编译器执行的优化较少,因此运行速度较慢。

除了占用更多磁盘空间这一事实之外,调试符号不是“开销”。以最大优化(-O3)编译的代码不应添加调试符号。这是你不需要所述符号时设置的标志。

如果需要调试符号,则可以通过丢失编译器优化为代价来获取它们。但是,再一次,这不是“开销”,它只是没有编译器优化。

答案 2 :(得分:2)

插入仪器的配置文件代码是否具有足够的功能来伤害您? 如果你单步使用汇编语言级别,你会发现很快。

答案 3 :(得分:0)

多线程代码执行时间并不总是按照gprof的预期进行测量。 除了gprof之外,您应该使用其他计时器为您的代码计时,以查看差异。

我的例子:在2NUMA节点上运行LULESH CORAL基准测试INTEL沙桥(8核+ 8核),大小为-50和20次迭代-i,使用gcc 6.3.0编译,-O3,我有:

运行1个线程: ~3,7 没有-pg和 ~3,8 ,但是根据gprof分析,代码只运行了3个, 5。

运行16个线程: ~0.6 没有-pg和 ~0,8 ,但是根据gprof分析,代码运行了~4, 5 ...

粗体的时间已经测量了gettimeofday,在并行区域之外(主函数的开始和结束)。

因此,如果您以相同的方式测量您的申请时间,您可能会看到相同的speeduo有和没有-pg。这只是并行错误的gprof措施。无论如何,在LULESH openmp版本中。