Отключение AVX2 в CPU для тестирования - PullRequest
8 голосов
/ 19 апреля 2019

У меня есть приложение, которое требует, чтобы AVX2 работал правильно.Была реализована проверка для проверки во время запуска приложения, есть ли у процессора инструкция AVX2.Я хотел бы проверить, работает ли он правильно, но у меня есть только процессор с AVX2.Есть ли способ временно отключить его в целях тестирования?Или как-то эмулировать другой процессор?

1 Ответ

5 голосов
/ 19 апреля 2019

Да, используйте слой «эмуляции» (или динамической перекомпиляции), например Эмулятор разработки программного обеспечения Intel (SDE) или, возможно, QEMU.

SDE - бесплатная программа с закрытым исходным кодом, которая очень удобна как для тестирования кода AVX512 на старых процессорах, так и для имитации старых процессоров, чтобы убедиться, что вы случайно не выполняете слишком новые инструкции.

Пример: у меня получился двоичный файл, который безоговорочно использует инструкцию загрузки AVX2 vpmovzxwq (для функции, которую я тестировал). Он нормально работает на моем процессоре Skylake, но SDE имеет опцию -snb, чтобы эмулировать Sandybridge в обоих CPUID и фактически проверять каждую инструкцию.

 $ 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 

Существуют опции для эмуляции процессоров таких же старых, как -quark, -p4 (SSE2) или Core 2 Merom (-mrm), до новых, таких как IceLake-Server (-icx) или Tremont (* 1018) *). (И процессоры Xeon Phi, такие как KNL и KNM.)

Он работает довольно быстро, с использованием динамической перекомпиляции (JIT), поэтому код, использующий только инструкции, которые поддерживаются изначально поддерживается, может работать в основном на собственной скорости, я думаю.

Он также имеет опции инструментария (например, -mix для вывода набора команд) и опции для более точного управления JIT. Я думаю, что вы могли бы заставить его не сообщать AVX2 в CPUID, но все же позволить инструкциям AVX2 работать без сбоев.

Или, возможно, эмулировать процессор, который поддерживает AVX2, но , а не FMA (к сожалению, существует настоящий процессор от Via). Или комбинации, которых нет у реального процессора, например AVX2, но не popcnt, или BMI1 / BMI2, но не AVX. Но я не изучал, как это сделать.

Базовые опции sde -help позволяют устанавливать только определенные Intel ЦП и проверять потенциально медленные переходы SSE / AVX (без правильного использования vzeroupper). И еще несколько вещей.

Одним из важных тестовых примеров, в котором отсутствует SDE, является AVX + FMA без AVX2 (AMD Piledriver / Steamroller, то есть большинство процессоров AMD FX-series). Это легко забыть и используйте перемешивание AVX2 в коде, который должен быть AVX1 + FMA3, и некоторые компиляторы (например, MSVC) не поймут это во время компиляции, как gcc -march=bdver2. (У Bulldozer есть только AVX + FMA4, а не FMA3, потому что Intel изменила свои планы после того, как AMD слишком поздно сменила дизайн.)


Если вы просто хотите, чтобы CPUID не сообщал о наличии AVX2 (и FMA?), Поэтому ваш код использует его версии функций AVX1 или не-AVX, вы можете сделать это с большинством виртуальных машин.

Чтобы команды AVX выполнялись без ошибок, в регистре управления должен быть установлен бит. (Таким образом, это работает как обещание ОС, что она будет правильно сохранять / восстанавливать новое архитектурное состояние верхних половин YMM). Таким образом, отключение AVX в CPUID даст вам экземпляр виртуальной машины, где ошибка инструкций AVX. (По крайней мере, 256-битные инструкции? Я не пробовал это проверить, могут ли 128-битные инструкции AVX все еще выполняться в этом состоянии на HW, который поддерживает AVX.)

...