一个简单的例子:
auto f(double*a,unsigned long const N)
{
for(auto i(0);i!=N;++i) a[i]+=2*i;
}
然后我使用g ++ -std = c ++ 1z -O2 -march = native -ftree-vectorize -fopt-info -S来编译源代码。输出显示:音符循环矢量化。那很好。
之后我想为这样的功能添加更积极的优化。所以我写道:
__attribute__((optimize("unroll-loops"))) auto f(double*a,unsigned long const N)
{
for(auto i(0);i!=N;++i) a[i]+=2*i;
}
然后我使用g ++ -std = c ++ 1z -O2 -march = native -ftree-vectorize -fopt-info -S来编译源代码。输出只显示:note循环展开7次。然后我检查asm文件并发现gcc只是执行unroll-loops优化但忽略了命令行中的tree-vectorize。
我也尝试使用:
#pragma GCC optimize("unroll-loops")
auto f(double*a,unsigned long const N)
{
for(auto i(0);i!=N;++i) a[i]+=2*i;
}
仍然无法正常工作。所以我想问一下如何保留命令行选项,但为某些功能添加更多优化标志。
我使用g ++ - 5.2,x86-64 linux和cpu支持avx2。
答案 0 :(得分:2)
来自GCC文档......
优化
optimize属性用于指定使用与命令行中指定的不同优化选项编译函数。参数可以是数字或字符串。假设数字是优化级别。假设以O开头的字符串是优化选项,而假定其他选项与-f前缀一起使用。您还可以使用'#pragma GCC optimize'编译指示来设置影响多个函数的优化选项。有关'#pragma GCC optimize'编译指示的详细信息,请参阅函数特定选项Pragma。
因此, optimize 属性和#pragma
不是相加的。您必须将所有必要的优化参数显式传递给属性。
例如......
__attribute__((optimize("O2", "tree-vectorize", "unroll-loops"))) auto f(double*a,unsigned long const N)
{
for(auto i(0);i!=N;++i) a[i]+=2*i;
}
但是,使用PGO可能会获得更好的结果,而不是显式地强制编译器使用特定的优化。