是否有任何研究或基准测试集表明指定GCC中的-fno-strict-aliasing(或其他编译器中的等效选项)会导致性能下降?
是否有任何研究或基准测试集表明指定GCC中的-fno-strict-aliasing(或其他编译器中的等效选项)会导致性能下降?
编译器之间的实现差异很大,不同编译器的实现级别也不一样。GCC非常积极:启用严格的别名规则会使它认为指针是“显然”等效的(如foo *a; bar *b = (bar *) a;
),从而允许进行一些非常积极的转换,但可能会破坏未经精心编写的代码。出于这个原因,苹果的GCC默认禁用严格别名。
相比之下,LLVM甚至没有严格的别名规则,并且虽然计划实现它,但开发人员表示计划在什么都不能确定时将其实现为后备方案。在上面的示例中,它仍然会判断a和b是等效的。它只有在无法以其他方式确定它们之间的关系时才使用基于类型的别名。
根据我的经验,严格的别名规则对性能的影响主要与循环不变式代码移动有关,其中类型信息可用于证明循环内加载不能与正在迭代的数组别名,从而允许将它们提取出来。结果可能因人而异。
-fstrict-aliasing
选项。 - Keith Smiley通过我的经验(在PS3上测试了一个大型项目,PowerPC是一种由于其很多寄存器而能够受益于SA的架构),我可以告诉你,你将看到的优化通常会非常局部(范围)和小。在一个20MB的可执行文件中,它仅削减了大约80kb的.text部分(=代码),而且这些都是在小范围和循环内进行的。
使用此选项可以使您生成的代码比现在更加轻量级和优化(考虑1到5%的范围内),但不要期望有任何大的成果。因此,使用-fno-strict-aliasing的影响可能对您的性能没有太大影响。尽管如此,编写需要-fno-strict-aliasing的代码通常是次优情况。
以下是一份2004年的研究报告链接:http://docs.lib.purdue.edu/cgi/viewcontent.cgi?article=1124&context=ecetr,其中探讨了严格别名对代码性能的影响等内容。图2.5显示相对提高了3%至10%的效果。
研究人员关于性能下降的解释:
通过检查汇编代码,我们发现性能下降是寄存器分配算法的影响。 GCC实现了一种图形着色寄存器分配器[2,3]。 由于存在严格别名,变量的生存期变得更长,导致寄存器压力过大而溢出。 相同的变量在更保守的别名方式下,也会在其(较短)生存期结束时发生内存转移。
[2] Peter Bergner、Peter Dahl、David Engebretsen和Matthew T.O’Keefe。 Spill code minimization via interference region spilling. In SIGPLAN Conference on Programming Language Design and Implementation, pages 287–295, 1997.
[3] Preston Briggs、Keith D.Cooper和Linda Torczon。 Improvements to graph coloring register allocation. ACM Transactions on Programming Languages and Systems, 16(3):428–455, May 1994.
restrict
限定符不能有效地告诉编译器静态持续时间对象不会别名,而且在某些情况下,程序可能有多个可能相关的指向相同类型的指针,它们可能会别名。基于类型的别名将允许在这些情况下进行一些优化,否则这些优化将不可用。在我看来,可以通过添加更好的限定符(例如,在对象可能暴露给外部代码但通过指针以外的方式访问时可能表现得好像它们获得了新地址时,允许 “register” 限定符)更好地处理这些情况。 - supercat// a simple test code
#include<vector>
void add(double *v, double *b, double *c, int *idx, std::vector<int> &v1) {
for(int i=v1[0];i<v1[2];i++){
v[i] = b[i] + c[i];
}
}
-O3 -ftree-vectorize -ftree-loop-vectorize -fopt-info-vec-missed -fopt-info-vec-optimized -fno-strict-aliasing
标志在https://godbolt.org/上编译代码,您将会看到以下消息:<source>:5:22: missed: couldn't vectorize loop
<source>:5:22: missed: not vectorized: number of iterations cannot be computed.
-fno-strict-aliasing
或将其替换为-fstrict-aliasing
,您会看到:<source>:5:22: optimized: loop vectorized using 16 byte vectors
<source>:5:22: optimized: loop versioned for vectorization because of possible aliasing