我想用-mavx -mprefer-avx128来优化单个函数.基本上所有的代码都不应该使用AVX,除了其中一个函数:这个函数应该使用AVX128.

我试过这些方法:

__attribute__((target("avx")))
void f() { ... }

=>似乎使用avx2

__attribute__((target("prefer-avx128")))
void f() { ... }

=>不编译

__attribute__((target("avx")))
__attribute__((optimize("prefer-avx128")))
void f() { ... }

=>不编译

也许有人知道如何做到这一点?

推荐答案

-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指令

C++相关问答推荐

设计处理各种数据类型的方法和数据 struct

C strlen on char array

C中的__attributor__((aligned(4),packed))与 struct 的用法

增加getaddrinfo返回的IP地址数量

C:二进制搜索和二进制插入

警告:C++中数组下标的类型为‘char’[-Wchar-subpts]

为什么GCC在每次循环迭代时都会生成一个数组的mov&S使用[]访问数组?(-03,x86)

正确的TCP/IP数据包 struct

在C++中通过空指针隐式访问常量变量的值

如何使用FSeek和文件流指针在C中查找文件的前一个元素和前一个减go 一个元素

我在反转双向链表时遇到问题

为什么Linux无法映射这个PT_LOAD ELF段?

CS50 pset 5的皱眉脸正确地处理了大多数基本单词,并且拼写判断不区分大小写.

程序如何解释变量中的值

';malloc():损坏的顶部大小';分配超过20万整数后

分配给静态变量和动态变量的位置之间有区别吗?

`%%的sscanf无法按预期工作

If语句默认为true

程序打印一些随机空行

当 a 是代码块时使用逗号运算符 (a, b)