是否有工具可以对程序进行别名分析,并告诉您gcc / g ++由于潜在的指针别名而必须在哪里生成次优指令序列?
答案 0 :(得分:4)
我不知道任何提供“100%”覆盖率的内容,但是对于矢量化代码(别名通常会阻止),请使用-ftree-vectorizer-verbose=n
选项,其中n是1到6之间的整数。这打印出来一些信息为什么循环无法矢量化。
例如,使用g ++ 4.1,代码
//#define RSTR __restrict__
#define RSTR
void addvec(float* RSTR a, float* b, int n)
{
for (int i = 0; i < n; i++)
a[i] = a[i] + b[i];
}
结果
$ g++ -ftree-vectorizer-verbose=1 -ftree-vectorize -O3 -c aliastest.cpp aliastest.cpp:6: note: vectorized 0 loops in function.
现在,切换到RSTR的另一个定义,你得到
$ g++ -ftree-vectorizer-verbose=1 -ftree-vectorize -O3 -c aliastest.cpp aliastest.cpp:6: note: LOOP VECTORIZED. aliastest.cpp:6: note: vectorized 1 loops in function.
有趣的是,如果切换到g ++ 4.4,它可以通过版本控制和运行时检查来矢量化第一个非限制性案例:
$ g++44 -ftree-vectorizer-verbose=1 -O3 -c aliastest.cpp aliastest.cpp:6: note: created 1 versioning for alias checks. aliastest.cpp:6: note: LOOP VECTORIZED. aliastest.cpp:4: note: vectorized 1 loops in function.
这两个RSTR定义都已完成。
答案 1 :(得分:1)
在过去,我通过探查器的一些帮助来跟踪案例混淆减速。一些游戏控制台分析器会突出显示导致大量load-hit-store penalties的部分代码 - 这些通常会发生,因为编译器假定某些指针有别名并且必须生成额外的加载指令。一旦你知道他们正在发生的代码部分,你可以从程序集回溯到源代码,看看可能被认为是别名的东西,并根据需要添加“restict”(或其他技巧以避免额外的负载)。
我不确定是否有任何免费的分析器可以让你进入这个级别的细节。
这种方法的另一个好处是,您只需花时间检查实际上会降低代码速度的案例。