将 AVX 与 GCC 一起使用:__builtin_ia32_addpd256 未声明
Posted
技术标签:
【中文标题】将 AVX 与 GCC 一起使用:__builtin_ia32_addpd256 未声明【英文标题】:Using AVX with GCC: __builtin_ia32_addpd256 not declared 【发布时间】:2013-09-18 08:30:28 【问题描述】:如果我#include <immintrin.h>
我得到这个错误:
错误:“__builtin_ia32_addpd256”未在此范围内声明
我已经定义了 __AVX__
和 __FMA__
宏来使 AVX 可用,但显然这还不够。如果我使用编译器标志 -mavx
而不是宏,则没有错误,但该解决方案是不可接受的。那么,我还应该定义什么来使用 AVX?
【问题讨论】:
您可能想详细说明-mavx
不是一个选项。毕竟,当实际上不允许编译器发出 avx 代码时,使用 avx-intrinsics 有点困难
【参考方案1】:
您不应该自己定义 __AVX__
和 __FMA__
- 当您启用正确的编译器选项时,它们会自动定义,例如
gcc -Wall -mavx ...
有兴趣的可以自行查看:
没有 AVX:
$ gcc -dM -E - < /dev/null | egrep "AVX|FMA"
$
AVX:
$ gcc -mavx -dM -E - < /dev/null | egrep "AVX|FMA"
#define __AVX__ 1
$
AVX + FMA:
$ gcc -mavx -mfma -dM -E - < /dev/null | egrep "AVX|FMA"
#define __AVX__ 1
#define __FMA__ 1
$
【讨论】:
我在问题中提到使用-mavx
是不可接受的。不过,感谢您展示查看定义的方式。
抱歉 - 错过了问题中的最后一句话 - 如果您不启用此编译器选项,您希望如何编译 AVX 代码,您为什么还要这样做?
我希望通过使用正确的定义使AVX
内在函数声明可用,并且我希望实现从运行时库链接。有什么问题?我不能使用-m
选项的原因是,在这种情况下,编译器会使用指定的指令集自动对我的代码进行矢量化,这会导致在不支持AVX+FMA 的CPU 上出现SIGILL
。我需要这些说明只出现在我明确使用了相应的内在函数的地方。
Intrinsics 不是那样工作的,它们不链接到任何东西 - 一般的想法是它们生成内联代码 - 如果你查看标题,你会看到每个内部映射到__builtin_XXX
编译器又使用它来生成相关的内联操作码。如果您不启用 AVX,那么编译器将无法处理 __builtin_XXX
s。
是的,我可以看到,这是我遇到问题的 __builtin
符号。你确定这不是常规函数吗?【参考方案2】:
正确的解决方案可能是拥有一个包含处理器特定内在函数的特定文件。并且您只为此文件设置了 -mavx -mfma 选项。程序本身决定在运行时调用哪个版本。
我使用 GCC 助手在运行时获得最佳优化版本。
func_avx_fma.c
void domagic_avx_fma(...)
func_general.c
void domagic_general(...)
helper.c
void domagic_avx_fma(...);
void domagic_general(...);
typedef void (*domagic_func_t)(...);
domagic_func_t resolve_domagic()
__builtin_cpu_init();
if (__builtin_cpu_supports("avx") && __builtin_cpu_supports("fma"))
return domagic_avx_fma;
return domagic_general;
void domagic(...) __attribute__ ((ifunc ("resolve_domagic")));
程序.c
void domagic(...);
int main()
domagic(...);
编译
$ gcc -c func_avx_fma.c -o func_avx_fma.o -O3 -mfma -mavx
$ gcc -c func_general.c -o func_general.o -O3
$ gcc -c helper.c -o helper.o
$ ...
这种方法在 x86 (x86_64) 上效果很好,但并非所有目标都支持这些帮助程序
【讨论】:
以上是关于将 AVX 与 GCC 一起使用:__builtin_ia32_addpd256 未声明的主要内容,如果未能解决你的问题,请参考以下文章
在 GCC 上设置打包的 long long 的正确对齐以与 avx2 指令一起使用
GCC __attribute__ 在 32 字节处对齐的 AVX 矢量化代码中的段错误
avr-gcc:如何将 __attribute__((address)) 与 EEMEM 一起使用?
防止 gcc 将我的 AVX2 内在函数复制到 REP MOVS