我正在尝试运行类似于以下代码
#include <immintrin.h>
void foo() {
__m128i a = _mm_set_epi8 (0,0,6,5,4,3,2,1,8,7,6,5,4,3,2,1);
__m128i b = _mm_set_epi8 (0,0,0,0,0,0,0,1,8,7,6,5,4,3,2,1);
__mmask16 m = _mm_cmpeq_epi8_mask(a,b); // supposedly requires avx512vl and avx512bw
std::cout<<m<<std::endl;
}
void bar() {
int dataa[8] = {1,0,1,0,1,0,1,0};
__m256i points = _mm256_lddqu_si256((__m256i *)&dataa[0]); // requires just mavx
(void)points;
}
但是,我一直遇到错误Illegal instruction (core dumped)
我用
编译代码g ++ -std = c ++ 11 -march = broadwell -mavx -mavx512vl -mavx512bw tests.cpp
根据Intel的内在文档,这些标志应足以同时运行foo
和bar
。但是,当运行foo
或bar
时,我会收到相同的错误消息。
但是,如果我删除了foo
,而没有进行-mavx512vl
的编译,则可以顺利运行bar
。
我已经检查过我的CPU是否支持mno-avx512vl
和mno-avx512bw
标志,因此它应该支持mavx512vl
和mavx512bw
吗?
我必须包括哪些标志才能运行这两个功能?还是我想念其他东西?
答案 0 :(得分:3)
恐怕您确定CPU功能的方法不正确 非常可靠。您的gcc编译器支持AVX-512的事实并不意味着 您的CPU支持AVX-512。
在Linux命令行上,输入more /proc/cpuinfo
并检查标志
部分以查看您的CPU支持哪些指令集。
在Windows上:1.打开设置,2.单击系统,3.单击关于。
这将显示处理器类型。谷歌
intel ark 'processor type'
,例如Google intel ark core i3 7100
。
然后点击指向processor page on the Intel website的链接并检查 Advanced Technologies
-> 指令集扩展项。
AVX-512支持许多级别。 AVX-512_BW AVX-512_VL是支持AVX-512的处理器的标准配置,除非您使用Knights Landing或Mill处理器。参见https://en.wikipedia.org/wiki/AVX-512#CPUs_with_AVX-512或https://en.wikichip.org/wiki/x86/avx-512#Implementation。
答案 1 :(得分:2)
使用gcc -march=native
进行编译。如果遇到编译错误,则您的源代码尝试使用您的CPU不支持的功能。
相关:Getting Illegal Instruction while running a basic Avx512 code
我已经检查过我的CPU是否支持mno-avx512vl和mno-avx512bw标志,因此它应该支持mavx512vl和mavx512bw吗?
这与GCC选项的工作方式相反。
-mno-avx512vl
禁用 -mavx512vl
,如果有任何较早的选项(例如-march=skylake-avx512
或-mavx512vl
本身)具有设置它。
-march=broadwell
未启用AVX512指令,因为Broadwell CPU无法在本地运行它们。因此,-mno-avx512vl
在g++ -std=c++11 -march=broadwell -mavx ...
的末尾具有完全零的作用
许多选项的长名称都以'-f'或'-W'开头,例如-fmove-loop-invariants,-Wformat等。 其中大多数都具有正面和负面形式; -ffoo的否定形式是-fno-foo。本手册仅介绍这两种形式中的一种,而不是默认形式。
GCC手册中section 3: Invoking GCC 3的简介部分
({-m
选项遵循与-f
和-W
长选项相同的约定。)
foo
与no-foo
的这种风格并非GCC独有;这很常见。
使用_mm256_lddqu_si256
编译后在-mavx512vl
上发生故障
GCC很笨,它对负载使用EVEX编码(可能是vmovdqu64
),而不是较短的VEX编码。但是您告诉它AVX512VL可用,因此这只是一个优化问题,而不是正确性。
如果仅在启用了AVX的情况下编译了该函数,则它当然只会使用AVX指令。
答案 2 :(得分:2)
对于Intel的ISA来说,一般规则是后者的架构是前者的超集。由于AVX512是您提到的最新版本,因此不必使用 -mavx 。使用 -march = broadwell 是没有用的,因为您无法针对没有AVX512 ISA的CPU进行优化。
您的命令行应该看起来像
g++ -std=c++11 -march=skylake-avx512 tests.cpp
此外,“我的CPU支持那些编译器标志”的语句很奇怪。我想您的意思是“使用这些标志构建的代码在我的CPU上运行”,但是正如前面已经提到的,否前缀意味着不会为这种ISA生成代码。< / p>
因此,您的编译器标记很好,因为您使用的CPU不支持所需的ISA。