【问题标题】:Compiling Options for Profiling Purpose用于分析目的的编译选项
【发布时间】:2014-02-03 20:01:33
【问题描述】:

为了提高我的分析实验的准确性,有哪些好的编译器选项可以打开/关闭?

我对这些编译器最感兴趣:gcc/g++/icc 和这些分析工具:Intel Vtune、Linux Perf 和 Oprofile。 Linux 操作系统。

众所周知,启用优化(函数内联、循环转换等)可能会改变指令的顺序,这可能会导致在分析器/调试器中显示混乱的信息(如果不是不正确的话)。但是,如果我禁用这些优化,我将分析(并稍后优化)“未优化”的代码......那么,编译分析时的最佳实践是什么?

【问题讨论】:

  • 您可以简单地使用gcc -pg 编译并使用gprof。但是剖析总是对被剖析的代码造成很大的干扰。阅读heisenbugs。另外,您要优化哪种应用程序,为什么?
  • 是“-pg”我需要做的唯一想法是使用我提到的工具获取准确的分析信息?我不限于特定类型的程序。
  • 恕我直言准确的分析oxymoron。剖析总是令人不安。你需要接受这一点。
  • 分析的目的是获得准确测量的想法是凭空而来的。假设你得到它们。即使它们“准确”,您会如何处理它们?他们会告诉你如何让它更快吗?如果目标是让代码更快,那么你需要一些东西来告诉你要修复什么,而不是给你 3 位数的精度。
  • 好吧,我没有说我想要数字精度。我很确定你们已经调试了一些优化的代码,并注意到指令的顺序发生了变化……许多分析器(例如 VTune)被这种转换误导了。寻找精确的代码注释不是来自其他世界的东西。

标签: linux performance gcc profiling icc


【解决方案1】:

所有分析工具都依赖于编译器在构建期间生成的调试信息。只要调试信息捕获了这些优化(尤其是内联),分析工具就能够将其映射到正确的源位置。对于 ICC,当您在启用优化的情况下构建代码时,请使用编译器选项“-debug inline-debug-info”。因此,如果您的函数是内联的,它将确保它会在调用站点和被调用站点(定义函数的位置)调用优化。下面是一个简单的例子,说明了这一点:

#include <iostream>
#include <tbb/tbb.h>
#include <tbb/parallel_for.h>
#include <cstdlib>
using namespace std;
using namespace tbb;
long len = 0;
float *__restrict__ a;
float *__restrict__ b;
float *__restrict__ c;
class Test {
public:
    void operator()( const blocked_range<size_t>& x ) const {
        for (long i=x.begin(); i!=x.end(); ++i ) {
            c[i] = (a[i] * b[i]) + b[i];
        }
    }
};
int main(int argc, char* argv[]) {
    cout << atol(argv[1]) << endl;
   len = atol(argv[1]);
    a = new float[len];
    b = new float[len];
    c = new float[len];
    parallel_for(blocked_range<size_t>(0,len, 100), Test() );
    return 0;
}

使用以下编译器选项构建上述代码会发出矢量化报告,该报告不会将矢量化报告映射到正确的源代码行:

$ icpc testdebug.cc -c -vec-report2 -O3
tbb/parallel_for.h(127): (col. 22) remark: loop was not vectorized: unsupported loop structure
tbb/parallel_for.h(127): (col. 22) remark: LOOP WAS VECTORIZED
tbb/parallel_for.h(127): (col. 22) remark: loop was not vectorized: unsupported loop structure
tbb/parallel_for.h(127): (col. 22) remark: LOOP WAS VECTORIZED
tbb/parallel_for.h(127): (col. 22) remark: loop was not vectorized: nonstandard loop is not a vectorization candidate
tbb/parallel_for.h(127): (col. 22) remark: loop was not vectorized: nonstandard loop is not a vectorization candidate
tbb/partitioner.h(164): (col. 9) remark: loop was not vectorized: existence of vector dependence

从上面的报告中,我们看到两条“LOOP WAS VECTORIZED”消息,但映射到parallel_for.h TBB 头。没有与我们程序中的函子相对应的报告。由于函子是在parallel_for 块中调用的,因此函数定义内联在parallel_for.h

为了捕获该信息,请在构建期间使用 -debug inline-debug-info 编译器选项,生成的矢量化报告将如下所示:

$ icpc testdebug.cc -c -vec-report2 -O3 -debug inline-debug-info
tbb/partitioner.h(171): (col. 9) remark: loop was not vectorized: unsupported loop structure
testdebug.cc(14): (col. 37) remark: LOOP WAS VECTORIZED
tbb/partitioner.h(164): (col. 9) remark: loop was not vectorized: unsupported loop structure
testdebug.cc(14): (col. 37) remark: LOOP WAS VECTORIZED
tbb/partitioner.h(245): (col. 33) remark: loop was not vectorized: nonstandard loop is not a vectorization candidate
tbb/partitioner.h(265): (col. 52) remark: loop was not vectorized: nonstandard loop is not a vectorization candidate
tbb/partitioner.h(164): (col. 9) remark: loop was not vectorized: existence of vector dependence

从上面的报告中可以清楚地看出,testdebug.cc(14) 中的“LOOP WAS VECTORIZED”。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-26
    • 1970-01-01
    • 2017-09-10
    • 1970-01-01
    相关资源
    最近更新 更多