-mprefer-avx128
,也就是现代的替代-mprefer-vector-width=128
,是-m
个选项,而不是-f
个,所以它们只能处理target("string")
个属性,而不是optimize("string")
个属性.
但实际上只有-m
个选项用作属性;这GCC manual's list of x86 target attributes个选项大多是ISA扩展,arch=
和tune=
,但也包括prefer-vector-width=OPT
.没有一个是基于较旧的选项-mprefer-avx128
的;可能是在-mprefer-avx128
被废弃后添加了对属性的支持,而支持-mprefer-vector-width
选项.
__attribute__((target("avx,prefer-vector-width=128")))
这将启用AVX(仅限AVX1,而不是AVX2),并针对128位自动矢量化进行调整.由于整数代码更容易自动矢量化,因此我实际使用AVX2进行了测试:
__attribute__((target("avx2,prefer-vector-width=128")))
unsigned foo(unsigned *arr){
unsigned sum=0;
for(int i=0 ; i<10240; i++) {
sum += arr[i];
}
return sum;
}
__attribute__((target("avx2")))
unsigned bar(unsigned *arr){
unsigned sum=0;
for(int i=0 ; i<10240; i++) {
sum += arr[i];
}
return sum;
}
用gcc -O3 -mtune=haswell
(Godbolt)编译,第一个版本使用vpaddd xmm
,第二个版本使用vpaddd ymm
.(Tune=Haswell将法线向量宽度首选项设置为256.)
Terminology: AVX1 supports 256-bit vector width for FP operations like vaddps
.
AVX2 is 256-bit integer operations like vpaddb ymm
, and lane-crossing shuffles with granularity finer than 128-bit like vpermps
/ vpermq
.
如果您还没有在命令行或更早的#pragma GCC target
中启用AVX2指令,__attribute__((target("avx")))
肯定不会使用AVX2指令