int add_a(float * restrict a, float * restrict b, int N)
{
a = (float*)__builtin_assume_aligned(a, 32);
b = (float*)__builtin_assume_aligned(b, 32);
N = N & 0xFFFFFFF8;
for (int i = 0; i < N; i++){
a[i] = a[i] + b[i];
}
return 0;
}
int add_b(float * restrict a, float * restrict b, int N)
{
a = (float*)__builtin_assume_aligned(a, 32);
b = (float*)__builtin_assume_aligned(b, 32);
for (int i = 0; i < N; i++){
a[i] = a[i] + b[i];
}
return 0;
}
3条答案
按热度按时间zy1mlcev1#
从gcc 4.8.2开始,gcc中没有__succept()的等价物,我不知道为什么--它会非常有用,mafso建议:
这是一个老把戏,至少在2010年甚至更久以前就知道了。编译器通常会优化掉“cond”的求值,因为任何cond为false的求值都是未定义的。但是,如果“cond”包含对opaque(非内联)函数。编译器必须假定不透明调用可能会产生副作用(例如改变全局)并且不能优化掉调用,尽管它可以优化掉结果上的任何计算和分支。宏观办法充其量只是部分解决办法。
sigwle7e2#
在您的示例中,您希望通知编译器
N
是8的倍数。只需插入以下行即可完成此操作这不会改变
N
,因为N
是8的倍数,但是自从GCC 4.9以来,编译器似乎理解了N
是8的倍数,在这一行之后。下一个示例显示了这一点,其中添加了两个浮点向量:
使用gcc版本4.9的
gcc -m64 -std=c99 -O3
,add_a
将编译为矢量化代码对于函数
add_b
,需要20多条额外指令来处理N
不是8的倍数的情况:参见Godbolt link。
bcs8qyzn3#
[[assume(...)]];
-C++23新增的可移植版本。__attribute__((__assume__(...)));
-在GCC 13中与上述内容一起添加,对C代码有用。