我正在写一个光线追踪器。
最近,我在程序中添加了线程,以利用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”在线程应用程序上都被破坏了,我只是删除它。
答案 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版本中。