Linux 用于分析目的的编译选项

Linux 用于分析目的的编译选项,linux,performance,gcc,profiling,icc,Linux,Performance,Gcc,Profiling,Icc,为了提高评测实验的准确性,需要打开/关闭哪些编译器选项 我最感兴趣的是这些编译器:gcc/g++/icc和这些评测工具:英特尔Vtune、Linux性能和Oprofile。Linux操作系统 众所周知,启用优化函数内联、循环转换等可能会改变指令的顺序,如果在探查器/调试器中显示的信息不正确,则可能会导致混淆信息。但是,如果我禁用这些优化,我将分析并稍后优化未优化的代码。。。那么,编译以进行评测时的最佳实践是什么呢?所有评测工具都依赖于编译器在构建过程中生成的调试信息。只要调试信息捕获了这些优化,

为了提高评测实验的准确性,需要打开/关闭哪些编译器选项

我最感兴趣的是这些编译器:gcc/g++/icc和这些评测工具:英特尔Vtune、Linux性能和Oprofile。Linux操作系统


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

所有评测工具都依赖于编译器在构建过程中生成的调试信息。只要调试信息捕获了这些优化,特别是内联优化,分析工具就能够将其映射到正确的源位置。对于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;
}
从上面的报告中,我们看到两个循环是矢量化的消息,但映射到.h TBB头的并行_。我们的程序中没有与函子对应的报告。由于函子是在parallel_for块中调用的,因此函数定义在parallel_for.h处内联

为了捕获该信息,请在生成过程中使用-debug inline debug info compiler选项,生成的矢量化报告如下所示:

$ 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.cc14处矢量化的

您可以简单地使用gcc-pg编译并使用gprof。但是评测总是会对评测代码造成很大的干扰。了解。另外,您正在尝试优化哪种应用程序,为什么?我认为使用我提到的工具,要获得准确的评测信息,只需要-pg吗?我并不局限于某一特定类型的程序。我认为准确的分析是一个关键。分析总是令人不安。你必须接受这一点。这种观点认为分析的目的是获得准确的测量结果,这是无中生有的。假设你得到了它们。即使它们是准确的,你怎么处理它们?他们会告诉你如何加快速度吗?如果目标是让代码更快,那么你需要的是告诉你要修复什么,而不是给你3位数的精度。我很确定你们已经调试了一些优化的代码,并且注意到指令的顺序已经改变了。。。许多分析器(例如VTune)都被这种转换误导了。寻找精确的代码注释并不是来自另一个世界。
$ 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