在 运行 基本 Avx512 代码时获取非法指令
Getting Illegal Instruction while running a basic Avx512 code
我正在尝试学习 AVX 指令,而 运行 我收到了基本代码
Illegal instruction (core dumped)
下面提到了代码,我正在使用
编译它
g++ -mavx512f 1.cpp
问题到底是什么以及如何克服它?
谢谢!
#include <immintrin.h>
#include<iostream>
using namespace std;
void add(const float a[], const float b[], float res[], int n)
{
int i = 0;
for(; i < (n&(~0x31)) ; i+=32 )
{
__m512 x = _mm512_loadu_ps( &a[i] );
__m512 y = _mm512_loadu_ps( &b[i] );
__m512 z = _mm512_add_ps(x,y);
_mm512_stream_ps(&res[i],z);
}
for(; i<n; i++) res[i] = a[i] + b[i];
}
int main()
{
int n = 100000;
float a[n], b[n], res[n];
for(int i = 0;i < n; i++)
{
a[i] = i;
b[i] = i+10;
}
add(a,b,res,n);
for(int i=0;i<n;i++) cout<<res[i]<<" ";
cout<<endl;
return 0;
}
可能您的 CPU 根本不支持 AVX512。
只有 CPU 这些和更新的世代 support AVX-512:
- Server/workstation:Skylake-SP(“至强可扩展性能”)及更高版本,
Skylake-X high-end desktop/workstation.
- 客户端:Ice Lake and later e.g. i5-1035G4, and Rocket Lake桌面,例如i5-11600.
(还有very-limited-releaseCannon Lake laptop chip)
这些的赛扬/奔腾版本有 AVX2 但没有 AVX-5121.
- Xeon Phi 计算卡,第 2 代及更高版本 (Knight's Landing)。
编译器选项
使用 clang 或 g++ -O3 -march=native
启用您的 CPU 支持的所有内容。
如果你遇到编译错误(比如未声明的函数 _mm512_loadu_ps
),你的 CPU 不 支持 AVX512 所以 g++ 没有启用它,所以immintrin.h
不会定义内在的。
(或者另一个可能的错误是“内联”目标选项不允许的内置错误。)
如果您想为其他 CPU 制作二进制文件,而不仅仅是您正在编译的机器,请仅使用单独的 -mavx512f
和 -mtune=
选项。
相关:How to test AVX-512 instructions w/o supported hardware?
- Intel AVX intrinsics: any compatibility library out?(在编译时模拟而不是 运行 时)。
MSVC 和 ICC do 允许您在不告诉编译器目标支持它们的情况下使用内部函数,因此这种根据 CPU 检查代码的方法不起作用与那些编译器。他们很乐意让您编译不会在当前 CPU 上 运行 的代码。 (因为 MSVC 假定您将进行 运行time CPU 检测和调度,而不是为每个人分发源代码以针对他们自己的机器进行优化。)
更多关于 CPUs 没有 AVX-512
英特尔processor name/number meanings
AMD 尚未发布任何 AVX-512 CPUs(谣言指向 Zen4),而较旧的 Intel 也没有。
Skylake-client没有有AVX-512,只有Skylake-server。
英特尔 Alder Lake hybrid (big.LITTLE) CPUs won't have AVX-512,即使在大核上也只有 AVX2。
Low-power CPUSilvermont / Tremont 甚至没有 AVX1。
另请注意,AVX-512 有多个扩展,例如 AVX-512VPOPCNTDQ,它引入了 SIMD 指令来计算每个 SIMD 元素中的设置位。检查 Wikipedia 的 CPUs with AVX-512 table 以查看哪个 CPU 有什么。 AVX-512F 是“基础”,AVX-512VL 允许在 128 位和 256 位向量上使用很酷的新指令。
脚注 1:Pentium/Celeron 旧版英特尔 CPU 甚至没有 AVX,只有 SSE4.2。 (也缺少 BMI1/2 因为他们禁用了 VEX 前缀的解码)。
我正在尝试学习 AVX 指令,而 运行 我收到了基本代码
Illegal instruction (core dumped)
下面提到了代码,我正在使用
编译它g++ -mavx512f 1.cpp
问题到底是什么以及如何克服它? 谢谢!
#include <immintrin.h>
#include<iostream>
using namespace std;
void add(const float a[], const float b[], float res[], int n)
{
int i = 0;
for(; i < (n&(~0x31)) ; i+=32 )
{
__m512 x = _mm512_loadu_ps( &a[i] );
__m512 y = _mm512_loadu_ps( &b[i] );
__m512 z = _mm512_add_ps(x,y);
_mm512_stream_ps(&res[i],z);
}
for(; i<n; i++) res[i] = a[i] + b[i];
}
int main()
{
int n = 100000;
float a[n], b[n], res[n];
for(int i = 0;i < n; i++)
{
a[i] = i;
b[i] = i+10;
}
add(a,b,res,n);
for(int i=0;i<n;i++) cout<<res[i]<<" ";
cout<<endl;
return 0;
}
可能您的 CPU 根本不支持 AVX512。
只有 CPU 这些和更新的世代 support AVX-512:
- Server/workstation:Skylake-SP(“至强可扩展性能”)及更高版本,
Skylake-X high-end desktop/workstation. - 客户端:Ice Lake and later e.g. i5-1035G4, and Rocket Lake桌面,例如i5-11600.
(还有very-limited-releaseCannon Lake laptop chip)
这些的赛扬/奔腾版本有 AVX2 但没有 AVX-5121. - Xeon Phi 计算卡,第 2 代及更高版本 (Knight's Landing)。
编译器选项
使用 clang 或 g++ -O3 -march=native
启用您的 CPU 支持的所有内容。
如果你遇到编译错误(比如未声明的函数 _mm512_loadu_ps
),你的 CPU 不 支持 AVX512 所以 g++ 没有启用它,所以immintrin.h
不会定义内在的。
(或者另一个可能的错误是“内联”目标选项不允许的内置错误。)
如果您想为其他 CPU 制作二进制文件,而不仅仅是您正在编译的机器,请仅使用单独的 -mavx512f
和 -mtune=
选项。
相关:How to test AVX-512 instructions w/o supported hardware?
- Intel AVX intrinsics: any compatibility library out?(在编译时模拟而不是 运行 时)。
MSVC 和 ICC do 允许您在不告诉编译器目标支持它们的情况下使用内部函数,因此这种根据 CPU 检查代码的方法不起作用与那些编译器。他们很乐意让您编译不会在当前 CPU 上 运行 的代码。 (因为 MSVC 假定您将进行 运行time CPU 检测和调度,而不是为每个人分发源代码以针对他们自己的机器进行优化。)
更多关于 CPUs 没有 AVX-512
英特尔processor name/number meanings
AMD 尚未发布任何 AVX-512 CPUs(谣言指向 Zen4),而较旧的 Intel 也没有。
Skylake-client没有有AVX-512,只有Skylake-server。
英特尔 Alder Lake hybrid (big.LITTLE) CPUs won't have AVX-512,即使在大核上也只有 AVX2。
Low-power CPUSilvermont / Tremont 甚至没有 AVX1。
另请注意,AVX-512 有多个扩展,例如 AVX-512VPOPCNTDQ,它引入了 SIMD 指令来计算每个 SIMD 元素中的设置位。检查 Wikipedia 的 CPUs with AVX-512 table 以查看哪个 CPU 有什么。 AVX-512F 是“基础”,AVX-512VL 允许在 128 位和 256 位向量上使用很酷的新指令。
脚注 1:Pentium/Celeron 旧版英特尔 CPU 甚至没有 AVX,只有 SSE4.2。 (也缺少 BMI1/2 因为他们禁用了 VEX 前缀的解码)。