Обнаружение функции AVX с использованием SIGILL против ЦП

Я пытаюсь определить эффективный метод определения доступности AVX и AVX2 на процессорах Intel и AMD. Я был немного удивлен, узнав, что он ближе к SSE и XSAVE, когда читал Руководство по разработке программного обеспечения Intel, том I (УПРАВЛЕНИЕ СОСТОЯНИЕМ С ИСПОЛЬЗОВАНИЕМ XSAVE FEATURE SET, стр. 310).

Корпорация Intel публикует некоторый код для определения доступности AVX при включенном AVX? Код показан ниже, и это не слишком больно. Проблема в том, что Visual Studio - это болевая точка, потому что нам нужно переместить код из файлов C/C++ ind в файлы ASM для X64.

Другие, кажется, принимают SIGILL подход к обнаружению доступности AVX. Или они невольно используют SIGILL метод. Смотрите, например, SIGILL по инструкции AVX.

Мой вопрос, безопасно ли использовать SIGILL метод определения доступности AVX? Здесь "безопасный" означает, что инструкция AVX не будет генерировать SIGILL когда процессор и ОС поддерживают AVX; и это сгенерирует SIGILL иначе.


Приведенный ниже код предназначен для 32-разрядных машин и из блога Intel. Включен ли AVX? Меня беспокоит манипулирование управляющими регистрами. Чтение и запись некоторых управляющих регистров X86 и ARM иногда требуют привилегий суперпользователя / администратора. Это причина, по которой я предпочитаю SIGILL (и избегайте контрольных регистров).

; int isAvxSupported();
isAvxSupported proc

  xor eax, eax
  cpuid
  cmp eax, 1           ; does CPUID support eax = 1?
  jb not_supported

  mov eax, 1
  cpuid
  and ecx, 018000000h  ; check 27 bit (OS uses XSAVE/XRSTOR)
  cmp ecx, 018000000h  ; and 28       (AVX supported by CPU)
  jne not_supported

  xor ecx, ecx         ; XFEATURE_ENABLED_MASK/XCR0 register number = 0
  xgetbv               ; XFEATURE_ENABLED_MASK register is in edx:eax
  and eax, 110b
  cmp eax, 110b        ; check the AVX registers restore at context switch
  jne not_supported

supported:
  mov eax, 1
  ret

not_supported:
  xor eax, eax
  ret

isAvxSupported endp

1 ответ

Решение

Сначала немного теории.

Для использования инструкций AVX необходимо выполнить несколько условий:

  1. CR4.OSXSAVE[bit 18] должно быть 1.
    Этот флаг устанавливается ОС, чтобы сигнализировать процессору, что он поддерживает xsave расширения.
    xsave расширения - единственный способ сохранить состояние AVX (fxsave не сохраняет ymm регистры) и таким образом ОС должна их поддерживать.

  2. XCR0.SSE[bit 1] а также XCR0.AVX[bit 2] должно быть 1.
    Эти флаги устанавливаются ОС для сигнализации процессору о том, что он поддерживает сохранение и восстановление состояний SSE и AVX (через xsave).

  3. CPUID.1:ECX.AVX[bit 28] = 1
    Конечно, процессор должен поддерживать расширения AVX в первую очередь.

Все эти регистры читаются в режиме пользователя, но для CR4,
К счастью, немного CR4.OSXSAVE отражается в CPUID.1:ECX.OSXSAVE[bit 27] и, таким образом, вся информация доступна в режиме пользователя. Никакие привилегированные инструкции не участвуют.

Для использования расширений AVX оба оборудования (CPUID.1:ECX.AVX а также CPUID.1:ECX.XSAVE) и ОС (CPUID.1:ECX.OSXSAVE, XCR0.SSE а также XCR0.AVX) поддержка должна присутствовать.
Поскольку ОС сигнализирует о своей поддержке xsave только при наличии аппаратной поддержки тестирование первого достаточно.
Для расширений AVX, тестирование CPUID.1:ECX.AVX все еще рекомендуется, так как ОС может установить XCR0.AVX даже если AVX не поддерживается.

Это приводит к использованию официального и настоятельно рекомендуемого алгоритма Intel:

Официальный алгоритм Intel для обнаружения AVX. Раздел 14.3 руководства 1

который является тем же самым, который Вы отправили.


Отлов исключений для определения поддержки расширений AVX также будет гарантирован, если вы гарантируете, что обнаруженное исключение - #UD.
Например, выполнив vzeroall единственными возможными исключениями являются #UD и #NM.
Первый бросается только тогда, когда:

Если XCR0[2:1] ≠ '11b'.
Если CR4.OSXSAVE[бит 18]=0.
Если CPUID.01H.ECX.AVX[бит 28]=0.
Если VEX.vvvv ≠ 1111B.

Таким образом, если у вас нет испорченного ассемблера / компилятора, это в точности соответствует условиям, указанным в начале.

Последнее выбрано как оптимизация для сохранения состояния AVX и, как таковое, не доступно для программ пользовательского режима ОС.

Тем самым ловить SIGILL на vzeroall или подобное также будет делать.

Другие вопросы по тегам