出于测试目的禁用CPU中的AVX2

Bib*_*iba 9 testing x86 instruction-set avx avx2

我有一个要求AVX2正常工作的应用程序。已实施检查以在应用程序启动期间检查CPU是否具有AVX2指令。我想检查它是否正常工作,但是我只有具有AVX2的CPU。有没有一种方法可以暂时将其关闭以进行测试?还是以某种方式模仿其他CPU?

Pet*_*des 6

是的,请使用“仿真”(或动态重新编译)层,例如英特尔的软件开发仿真器(SDE)或QEMU。

SDE是开源的免费软件,非常方便用于在旧CPU上测试AVX512代码,或用于仿真旧CPU以检查您是否不会意外执行太新的指令。

示例:我碰巧有一个二进制文件,该二进制文件无条件使用AVX2 vpmovzxwq加载指令(对于我正在测试的功能)。它可以在我的Skylake CPU上正常运行,但是SDE可以-snb选择在两个CPUID中模拟Sandybridge并实际检查每条指令。

 $ sde64 -snb -- ./mask
TID 0 SDE-ERROR: Executed instruction not valid for specified chip (SANDYBRIDGE): 0x401005: vpmovzxwq ymm2, qword ptr [rip+0xff2]
Image: /tmp/mask+0x5 (in multi-region image, region# 1)
Instruction bytes are: c4 e2 7d 34 15 f2 0f 00 00 
Run Code Online (Sandbox Code Playgroud)

有选择效仿的CPU一样古老-quark-p4(SSE2),或酷睿2 Merom处理器(-mrm),到像新的一样IceLake -服务器(-icx)或特里蒙特(-tnt)。(还有XNL Phi CPU,例如KNL和KNM。)

它运行得很快,所以只使用指令代码中使用动态重新编译(JIT)原生支持可在基本原生速度运行,我想。

它还具有检测选项(例如-mix转储指令混合),以及用于更紧密地控制JIT的选项。我认为您可能会得到它不报告CPUID中的AVX2,但仍然让AVX2指令运行而不会出错。

或者可能是模拟一个支持AVX2但支持FMA的CPU(不幸的是,有一个真正的CPU来自Via)。或没有真正CPU的组合,例如AVX2但不是popcnt,或者BMI1 / BMI2但不是AVX。但是我还没有研究如何做到这一点。

基本sde -help选项仅允许您将其设置为特定的Intel CPU,并用于检查可能缓慢的SSE / AVX转换(没有正确使用vzeroupper用法)。还有其他一些事情。

缺少SDE的一个重要测试用例是没有 AVX2(AMD Piledriver / Steamroller,即大多数AMD FX系列CPU)的AVX + FMA 。 很容易忘记并在应该为AVX1 + FMA3的代码中使用AVX2随机播放,并且某些编译器(如MSVC)在编译时不会像以前那样捕捉到这一点gcc -march=bdver2。(推土机只有AVX + FMA4,没有FMA3,因为英特尔在AMD重新设计为时已晚之后改变了计划。)


如果只希望CPUID不报告AVX2(和FMA?)的存在,以便您的代码使用其AVX1或非AVX版本的功能,则可以对大多数VM执行此操作。

为了使AVX指令正常运行,必须将控制寄存器中的位置1。(因此,这就像操作系统承诺的那样,它将正确保存/恢复YMM上半部分的新架构状态)。因此,在CPUID中禁用AVX将为您提供一个VMX实例出现故障的VM实例。(至少256位指令?我还没有尝试过看看是否可以在支持AVX的硬件上以这种状态执行128位AVX指令。)