我有一个需要AVX2正常运行的应用程序。已实施检查以在应用程序启动期间检查CPU是否具有AVX2指令。我想检查它是否正常工作,但是我只有具有AVX2的CPU。有没有一种方法可以暂时将其关闭以进行测试?还是以某种方式模仿其他CPU?
答案 0 :(得分:5)
是的,请使用Intel's Software Development Emulator (SDE)之类的“仿真”(或动态重新编译)层,或者使用QEMU。
SDE是开源免费软件,非常方便用于在旧CPU上测试AVX512代码,或模拟旧CPU以检查您是否不会意外执行太新的指令。< / p>
示例:我碰巧有一个二进制文件,该二进制文件无条件地使用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
可以使用以下选项来仿真旧的CPU:-quark
,-p4
(SSE2)或Core 2 Merom(-mrm
),以及最新的IceLake-Server({{1 }})或Tremont(-icx
)。 (还有KNL和KNM等Xeon Phi CPU。)
使用动态重新编译(JIT),它运行非常快,因此,我认为仅使用受本机支持的指令的代码就可以以本机速度运行。
它还具有检测选项(例如-tnt
,用于转储指令混合),以及用于更紧密地控制JIT的选项。我认为您可能会得到它不报告CPUID中的AVX2,但仍然让AVX2指令运行没有错误。
或者可能模拟支持AVX2但不支持FMA的CPU(不幸的是,有Via提供的真正的CPU这样的)。或没有真正CPU的组合,例如AVX2但没有-mix
,或BMI1 / BMI2但没有AVX。但是我还没有研究如何做到这一点。
基本的popcnt
选项仅允许您将其设置为特定的 Intel CPU,并用于检查可能缓慢的SSE / AVX转换(没有正确使用vzeroupper)。还有其他一些东西。
缺少SDE的一个重要测试用例是AVX + FMA 没有 AVX2(AMD Piledriver / Steamroller,即大多数AMD FX系列CPU)。忘记并在应该为AVX1 + FMA3的代码中使用AVX2随机播放,某些编译器(如MSVC)将无法像sde -help
那样在编译时捕获到这种情况。 (推土机只有AVX + FMA4,没有FMA3,因为在AMD重新设计为时已晚之后,英特尔改变了他们的计划。)
如果只希望CPUID不报告AVX2(和FMA?)的存在,以便您的代码使用其AVX1或非AVX版本的功能,则可以对大多数VM执行此操作。
要使AVX指令正常运行,必须将控制寄存器中的位置1。 (因此,这就像操作系统承诺的那样,它将正确保存/恢复YMM上半部分的新体系结构状态)。因此,在CPUID中禁用AVX将为您提供一个VMX实例出现故障的VM实例。 (至少有256位指令?我没有尝试过看看是否可以在支持AVX的硬件上以这种状态执行128位AVX指令。)