Наборы инструкций по битовой манипуляции ( наборы BMI ) являются расширениями архитектуры набора инструкций x86 для микропроцессоров Intel и AMD . Целью этих наборов инструкций является повышение скорости битовой манипуляции . Все инструкции в этих наборах не являются SIMD и работают только с регистрами общего назначения .
Intel опубликовала два набора: BMI (теперь называемый BMI1) и BMI2; они оба были введены с микроархитектурой Haswell с BMI1, соответствующими функциями, предлагаемыми набором инструкций AMD ABM, и BMI2, расширяющим их. AMD опубликовала еще два набора: ABM ( Advanced Bit Manipulation , который также является подмножеством SSE4a , реализованным Intel как часть SSE4.2 и BMI1), и TBM ( Trailing Bit Manipulation , расширение, представленное с процессорами на базе Piledriver в качестве расширения BMI1, но снова исключенное в процессорах на базе Zen ). [1]
AMD была первой, кто представил инструкции, которые теперь формируют BMI1 от Intel как часть своего набора инструкций ABM ( Advanced Bit Manipulation ), а затем добавила поддержку новых инструкций BMI2 от Intel. Сегодня AMD объявляет о доступности этих функций через BMI1 и BMI2 cpuflags от Intel и инструктирует программистов нацеливаться на них соответствующим образом. [2]
В то время как Intel рассматривает POPCNT
как часть SSE4.2 и LZCNT
как часть BMI1, и Intel, и AMD объявляют о наличии этих двух инструкций по отдельности. POPCNT
имеет отдельный флаг CPUID с тем же именем, а Intel и AMD используют флаг AMD ABM
для указания LZCNT
поддержки (поскольку LZCNT
в сочетании с BMI1 и BMI2 завершает расширенный набор инструкций ABM). [2] [3]
LZCNT
связана с BSR
инструкцией Bit Scan Reverse ( ), но устанавливает флаги ZF (если результат равен нулю) и CF (если источник равен нулю), а не устанавливает флаг ZF (если источник равен нулю). Кроме того, она выдает определенный результат (размер исходного операнда в битах), если исходный операнд равен нулю. Для ненулевого аргумента сумма LZCNT
и BSR
результатов равна битовой ширине аргумента минус 1 (например, если 32-битный аргумент равен 0x000f0000
, LZCNT дает 12, а BSR дает 19).
Кодировка LZCNT
такова, что если ABM не поддерживается, то BSR
вместо этого выполняется инструкция. [4] : 227
Приведенные ниже инструкции включаются битом BMI
в CPUID. Intel официально рассматривает LZCNT
как часть BMI, но объявляет LZCNT
о поддержке с помощью ABM
флага функции CPUID. [3] BMI1 доступен в процессорах AMD Jaguar , [5] Piledriver [6] и более новых процессорах, а также в процессорах Intel Haswell [7] и более новых процессорах.
TZCNT
почти идентична BSF
инструкции Bit Scan Forward ( ), но устанавливает флаги ZF (если результат равен нулю) и CF (если источник равен нулю) вместо установки ZF (если источник равен нулю). Для ненулевого аргумента результат TZCNT
и BSF
равен.
Как и в случае с LZCNT
, кодировка TZCNT
такова, что если BMI1 не поддерживается, то BSF
вместо этого выполняется инструкция. [4] : 352
Intel представила BMI2 вместе с BMI1 в своей линейке процессоров Haswell. Только AMD выпустила процессоры с поддержкой BMI1 без BMI2; BMI2 поддерживается архитектурой AMD Excavator и более новыми. [11]
Инструкции PDEP
и PEXT
являются новыми обобщенными инструкциями сжатия и расширения на уровне битов. Они принимают два входа: один является источником, а другой — селектором. Селектор — это битовая карта, выбирающая биты, которые должны быть упакованы или распакованы. PEXT
копирует выбранные биты из источника в смежные младшие биты назначения; старшие биты назначения очищаются. PDEP
делает противоположное для выбранных битов: смежные младшие биты копируются в выбранные биты назначения; другие биты назначения очищаются. Это можно использовать для извлечения любого битового поля ввода и даже для выполнения большого количества перетасовок на уровне битов, которые ранее были бы дорогими. Хотя то, что делают эти инструкции, похоже на инструкции SIMD для сбора-рассеиванияPDEP
на уровне битов, и PEXT
инструкции (как и остальные наборы инструкций BMI) работают с регистрами общего назначения. [12]
Инструкции доступны в 32- и 64-битной версиях. Пример использования произвольного источника и селектора в 32-битном режиме:
Процессоры AMD до Zen 3 [13] , реализующие PDEP и PEXT, делают это в микрокоде с задержкой 18 циклов [14] вместо 3 циклов (Zen 3). [15] В результате на этих процессорах часто быстрее использовать другие инструкции. [16]
TBM состоит из инструкций, дополнительных к набору инструкций, начатому BMI1; их дополнительная природа означает, что они не обязательно должны использоваться напрямую, но могут быть сгенерированы оптимизирующим компилятором, если поддерживаются. AMD представила TBM вместе с BMI1 в своей линейке процессоров Piledriver [6] ; более поздние процессоры AMD Jaguar и Zen не поддерживают TBM. [5] Ни один процессор Intel (по крайней мере, вплоть до Alder Lake ) не поддерживает TBM.
Обратите внимание, что поддержка расширения инструкций означает, что процессор способен выполнять поддерживаемые инструкции для целей совместимости программного обеспечения. При этом процессор может работать не очень хорошо. Например, процессоры Excavator — Zen 2 реализуют инструкции PEXT и PDEP с помощью микрокода, что приводит к тому, что инструкции выполняются значительно медленнее, чем то же самое поведение, воссозданное с использованием других инструкций. [20] (Программный метод под названием «zp7» на самом деле быстрее на этих машинах.) [21] Для оптимальной производительности разработчикам компиляторов рекомендуется использовать отдельные инструкции в расширениях на основе профилей производительности, специфичных для архитектуры, а не на доступности расширений.