Как и большинство ISA, x86 развивается.
Некоторые ISA прерывают обратное сравнение, переопределяя существующие коды операций (например, MIPS64r6 сделал это), но это довольно редко.например, MIPS32r6 / MIPS64r6 является примером этого: https://en.wikipedia.org/wiki/MIPS_architecture#MIPS32/MIPS64_Release_6 переопределение нескольких кодировок, а также удаление нескольких инструкций.
x86 имеет никогда не прервано в обратном направлении:Ryzen или Skylake-X все еще могли загружаться и запускать машинный код, который работал на 8086 .Это часть того, что значит быть процессором x86: см. Также Начало x86: Intel 8080 против Intel 8086? .(Мы просто говорим о машинном коде, но даже устройства ввода-вывода эмулируются, если вы загружаете ПК в устаревшем режиме BIOS, а не в UEFI, поэтому очень ранняя ОС 8086 для ПК, такая как ранняя DOS, может фактически работать естественным образом.)
Intel и AMD доводят это до такой степени, что недокументированные 8086 инструкции, такие как SALC (например, sbb al,al
, но без обновления FLAGS), все еще поддерживаются в 16- и 32-битном режиме на текущих процессорах, используя доценное пространство кодирования кода операции, которое можно использовать для более коротких кодировок для новых инструкций.
Но ПО, использующее новые insns, работает только на новом HW.Новое программное обеспечение будет работать на текущем и будущем оборудовании, а старое оборудование - до тех пор, пока оно не станет совместимым.(Например, в 32-битном коде вы можете не использовать cmov
или другие инструкции, которые были впервые введены в Pentium Pro, поэтому ваш код может работать на P5 (i586) Pentium / PMMX.)
x86-64 setновый базовый уровень, включающий SSE2 и инструкции PPro, такие как cmov
.Так что, к счастью, 64-битному коду не нужно беспокоиться о совместимости со старыми процессорами, которые не имеют таких вещей, они необходимы для x86-64.
Новый базовый уровень, который включает AVX2, FMA,и BMI2 (например, Haswell) было бы неплохо.BMI1 / BMI2 особенно полезны, если ваш компилятор может использовать их повсюду в коде для более эффективных инструкций сдвига с переменным числом и т. Д., А не только в виде пары горячих циклов, как в инструкциях SIMD.Но Intel все еще продает новые процессоры без BMI2 (например, версии Skylake / Coffee Lake для Pentium / Celeron).
Если нет, то что произойдет?
Инструкции, не поддерживаемые ЦП, обычно выдают ошибку с #UD
(Не определено) .В Unix-подобных ОС ваш процесс получит сигнал SIGILL (Illegal).
Единственный способ создать один двоичный файл, который будет использовать преимущества новых инструкций, но не будет вызывать сбои недопустимых инструкций на старых процессорах, - это выполнять во время выполненияОбнаружение ЦП и динамическая диспетчеризация. Некоторые компиляторы могут сделать это за вас.
Новые инструкции могут иметь кодировку, которая (на старых ЦП) выглядит как избыточный префикс для другой инструкции. Например, lzcnt
на процессоре, который не поддерживает его, будет декодироваться как rep bsr
, который работает как bsr
. И дает результат, отличный от lzcnt
!
(документы Intel явно указывают на то, что будущие процессорыне гарантируется декодирование инструкций с бессмысленными префиксами так же, как это делают нынешние процессоры. Это оставляет им пространство для создания расширений ISA таким образом.)
Иногда беззвучное игнорирование бессмысленных префиксов REP на старых процессорахполезно для расширений ISA, например, pause
равно rep nop
. Очень полезно, чтобы он декодировалбезвредно для старых процессоров, позволяя помещать его в циклы без проверки.Точно так же аппаратное блокирование (транзакционная память) декодирует код, который все еще работает на старых процессорах, фактически делая атомарные операции вместо начала транзакции.
См. Также: https://www.agner.org/optimize/blog/read.php?i=25 Остановить войну с набором команд, автор Agner Fog.Некоторая история о том, что Intel перешагнула через AMD, не раскрывая подробностей о будущих расширениях ISA, поэтому AMD заканчивает разработку собственных несовместимых и тратит больше лет на добавление поддержки нового расширения для своих собственных процессоров.(Например, SSSE3 не был доступен на процессорах AMD до Bulldozer, а это означает, что даже игры, для которых требуются компьютеры нового поколения, не могли требовать его в качестве базового уровня в течение многих лет.)
Новведенные новые инструкции, позволяющие сделать то, что нельзя было сделать ранее?
Да, SIMD является одним из наиболее важных примеров.MMX, затем SSE / SSE2, затем SSE4.x.Тогда AVX для вдвое больше широких векторов.Параллельная обработка целого вектора из 16 или 32 байтов данных дает огромное ускорение для таких вещей, как strlen
или memcmp
по сравнению с циклом байтов за раз.Также очень полезно для большого количества массивов.
AVX2, какой самый эффективный способ упаковки влево на основе маски? - интересный пример новых приемов, допускаемых новыми наборами команд.например, AVX512 имеет эту встроенную операцию, в то время как AVX2 + BMI2 допускает трюки с pdep
/ pext
, которые раньше были невозможны.
SSSE3 pshufb
- первая команда тасования с переменным управлением, изагрузка shuffle-control из справочной таблицы позволяет делать вещи, которые ранее были невозможны эффективно.например, Самый быстрый способ получить IPv4-адрес из строки .
Как реализовать atoi с помощью SIMD? также показывает некоторые изящные вещи, которые вы можете сделать с x86 pmaddubsw
/ pmaddwd
целочисленное умножение + горизонтальное добавление инструкций для умножения на десятичные знаки-места.
Более ранняя история новых инструкций, добавляемых после 8086, хорошо документирована в старой версии руководства NASM, в приложении .В текущих версиях этого приложения удалены текстовые описания каждой инструкции, чтобы освободить место для SIMD-инструкций.(Их много.)
A.77 IMUL: Signed Integer Multiply
IMUL r/m8 ; F6 /5 [8086]
IMUL r/m16 ; o16 F7 /5 [8086]
IMUL r/m32 ; o32 F7 /5 [386]
IMUL reg16,r/m16 ; o16 0F AF /r [386]
IMUL reg32,r/m32 ; o32 0F AF /r [386]
IMUL reg16,imm8 ; o16 6B /r ib [286]
IMUL reg16,imm16 ; o16 69 /r iw [286]
IMUL reg32,imm8 ; o32 6B /r ib [386]
IMUL reg32,imm32 ; o32 69 /r id [386]
IMUL reg16,r/m16,imm8 ; o16 6B /r ib [286]
IMUL reg16,r/m16,imm16 ; o16 69 /r iw [286]
IMUL reg32,r/m32,imm8 ; o32 6B /r ib [386]
IMUL reg32,r/m32,imm32 ; o32 69 /r id [386]
Конечно, любая инструкция reg32 требует 386 для 32-разрядных расширений, но обратите внимание, что imul-немедленный был новым в 286 (imul cx, [bx], 123
), в то время как2-операнд imul был новым в 386 (imul cx, [bx]
) , позволяя умножать без ударов DX: AX, делая AX менее "особенным".
Другие 386 инструкции, такие как movsx
и movzx
такжепрошел долгий путь к тому, чтобы сделать регистры более ортогональными, позволяя эффективно входить в любой регистр.До этого вам приходилось переносить данные в AL и использовать cbw
или в AX для cwd
, чтобы подписать расширение в DX: AX.