c++ - 错误:“_mm512_loadu_epi64”未在此范围内声明
问题描述
我正在尝试为此问题报告创建一个最小的复制器。AVX-512 似乎存在一些问题,它在配备 Skylake 处理器的最新 Apple 机器上发货。
根据GCC6 发布说明,应该可以使用 AVX-512 设备。根据Intel Intrinsics Guide vmovdqu64
可用于AVX-512VL
和AVX-512F
:
$ cat test.cxx
#include <cstdint>
#include <immintrin.h>
int main(int argc, char* argv[])
{
uint64_t x[8];
__m512i y = _mm512_loadu_epi64(x);
return 0;
}
接着:
$ /opt/local/bin/g++-mp-6 -mavx512f -Wa,-q test.cxx -o test.exe
test.cxx: In function 'int main(int, char**)':
test.cxx:6:37: error: '_mm512_loadu_epi64' was not declared in this scope
__m512i y = _mm512_loadu_epi64(x);
^
$ /opt/local/bin/g++-mp-6 -mavx -mavx2 -mavx512f -Wa,-q test.cxx -o test.exe
test.cxx: In function 'int main(int, char**)':
test.cxx:6:37: error: '_mm512_loadu_epi64' was not declared in this scope
__m512i y = _mm512_loadu_epi64(x);
^
$ /opt/local/bin/g++-mp-6 -msse4.1 -msse4.2 -mavx -mavx2 -mavx512f -Wa,-q test.cxx -o test.exe
test.cxx: In function 'int main(int, char**)':
test.cxx:6:37: error: '_mm512_loadu_epi64' was not declared in this scope
__m512i y = _mm512_loadu_epi64(x);
^
我把选项带回去了,-msse2
但没有成功。我似乎错过了什么。
为现代 GCC 使用 AVX-512 需要什么?
根据 a /opt/local/bin/g++-mp-6 -v
,这些是标头搜索路径:
#include "..." search starts here:
#include <...> search starts here:
/opt/local/include/gcc6/c++/
/opt/local/include/gcc6/c++//x86_64-apple-darwin13
/opt/local/include/gcc6/c++//backward
/opt/local/lib/gcc6/gcc/x86_64-apple-darwin13/6.5.0/include
/opt/local/include
/opt/local/lib/gcc6/gcc/x86_64-apple-darwin13/6.5.0/include-fixed
/usr/include
/System/Library/Frameworks
/Library/Frameworks
接着:
$ grep -R '_mm512_' /opt/local/lib/gcc6/ | grep avx512f | head -n 8
/opt/local/lib/gcc6//gcc/x86_64-apple-darwin13/6.5.0/include/avx512fintrin.h:_mm512_set_epi64 (long long __A, long long __B, long long __C,
/opt/local/lib/gcc6//gcc/x86_64-apple-darwin13/6.5.0/include/avx512fintrin.h:_mm512_set_epi32 (int __A, int __B, int __C, int __D,
/opt/local/lib/gcc6//gcc/x86_64-apple-darwin13/6.5.0/include/avx512fintrin.h:_mm512_set_pd (double __A, double __B, double __C, double __D,
/opt/local/lib/gcc6//gcc/x86_64-apple-darwin13/6.5.0/include/avx512fintrin.h:_mm512_set_ps (float __A, float __B, float __C, float __D,
/opt/local/lib/gcc6//gcc/x86_64-apple-darwin13/6.5.0/include/avx512fintrin.h:#define _mm512_setr_epi64(e0,e1,e2,e3,e4,e5,e6,e7) \
/opt/local/lib/gcc6//gcc/x86_64-apple-darwin13/6.5.0/include/avx512fintrin.h: _mm512_set_epi64(e7,e6,e5,e4,e3,e2,e1,e0)
/opt/local/lib/gcc6//gcc/x86_64-apple-darwin13/6.5.0/include/avx512fintrin.h:#define _mm512_setr_epi32(e0,e1,e2,e3,e4,e5,e6,e7, \
/opt/local/lib/gcc6//gcc/x86_64-apple-darwin13/6.5.0/include/avx512fintrin.h: _mm512_set_epi32(e15,e14,e13,e12,e11,e10,e9,e8,e7,e6,e5,e4,e3,e2,e1,e0)
...
解决方案
没有屏蔽,就没有理由存在或使用它来代替等价的_mm512_loadu_si512
. 这只是令人困惑,并且可能会诱使人类读者认为这是vmovq
单个epi64
.
英特尔的内在函数查找器确实指定它存在,但即使是当前的主干 gcc(在 Godbolt 上)也没有定义它。
几乎所有的 AVX512 指令都支持合并屏蔽和零屏蔽。过去是纯按位/全寄存器且没有有意义的元素边界的指令现在有 32 位和 64 位元素风格,例如vpxord
和vpxorq
. 或vmovdqa32
和vmovdqa64
。但是使用没有掩码的任何一个版本仍然只是一个正常的向量加载/存储/寄存器复制,并且在具有内在函数的 C++ 源代码中为它们指定任何关于元素大小的任何内容都是没有意义的,只有总向量宽度。
另请参阅_mm512_load_epi32 和 _mm512_load_si512 有什么区别?
SSE* 和 AVX1/2 选项与 GCC 标头是否根据 gcc 内置函数定义此内在函数无关;-mavx512f
已经暗示了 AVX512 之前的所有英特尔 SSE/AVX 扩展。
它存在于 clang 主干中(但不是 7.0,所以它是最近才添加的)。
- unaligned
_mm512_loadu_si512
- 到处都支持,使用这个 - 未对齐
_mm512_loadu_epi64
- 铿锵的树干,而不是 gcc。 - 对齐
_mm512_load_si512
- 到处都支持,使用这个 - 对齐
_mm512_load_epi64
- 也支持无处不在,令人惊讶。 - 未对齐
_mm512_maskz_loadu_epi64
- 随处支持,将其用于零掩码负载 - unaligned
_mm512_mask_loadu_epi64
- 随处支持,将其用于合并掩码加载。
这段代码早在 4.9.0 就可以在 gcc 上编译,而 mainline (Linux) 早在 3.9 就可以编译,两者都带有-march=avx512f
. 或者如果他们支持它,-march=skylake-avx512
或者-march=knl
。我没有用 Apple Clang 测试过。
#include <immintrin.h>
__m512i loadu_si512(void *x) { return _mm512_loadu_si512(x); }
__m512i load_epi64(void *x) { return _mm512_load_epi64(x); }
//__m512i loadu_epi64(void *x) { return _mm512_loadu_epi64(x); }
__m512i loadu_maskz(void *x) { return _mm512_maskz_loadu_epi64(0xf0, x); }
__m512i loadu_mask(void *x) { return _mm512_mask_loadu_epi64(_mm512_setzero_si512(), 0xf0, x); }
神螺栓链接;您可以取消注释_mm512_loadu_epi64
并将编译器翻转到 clang trunk 以查看它在那里工作。
推荐阅读
- r - R - 在创建具有列名的新变量时合并数据框
- c++ - C ++从输入文件读取到结构数组
- javascript - 组件事件处理程序接收列表中不同组件的道具
- roblox - Roblox:BindToClose 有效,PlayerRemoving 无效
- pandas - matplotlib 问题:如何擦除这个?
- php - Symfony - 进程运行抛出异常 - 在命令行上执行有效
- c# - 在 C# 中使用 ExtraParams 从 Stripe 的 API 中提取特定事件
- arrays - 根据条件切片,否则返回空数组
- r - 有没有办法通过 r 代码选择 Shift F3
- build.gradle - androidx 的 Android Studio 支持库