, поэтому использование регистров rN имеет больший размер кода, чем при использовании других регистров
Да, это хорошо известный и документированный факт. Префиксы REX являются одним из наиболее важных изменений в машинном коде x86-64 по сравнению с более ранними режимами, и на этот вопрос стоит ответить только для части производительности (см. Ниже).
машинный код x86 имеет только 3-битные поля для регистров. 4-й бит, если он не равен нулю, должен исходить из префикса REX.
Это то, для чего AMD64 перепрофилировала байты кода операции 0x4?
(в 32-битном машинном коде они 1- byte inc / de c reg инструкции).
Разрешение декодирования x86-64 на тех же транзисторах, что и в декодировании в 16/32-битном режиме, вместо необходимости полного нового блока декодера во внешнем интерфейсе AMD предпочла не перепроектировать машинный код x86 с нуля. Поэтому они застряли с 3-битными полями для регистров и должны были использовать префиксный байт.
Прочтите руководство Intel vol.2 для получения дополнительной информации о префиксах REX. Или https://wiki.osdev.org/X86-64_Instruction_Encoding#REX_prefix содержит некоторые полезные вещи, включая детали того, что означают эти биты. Это также объясняет:
Префикс REX должен быть закодирован, когда:
- с использованием размера 64-битного операнда и инструкция не по умолчанию имеет размер 64-битного операнда (большинство по умолчанию инструкции имеют размер 32-битного операнда); или
- с использованием одного из расширенных регистров (от R8 до R15, от XMM8 до XMM15, от YMM8 до YMM15, от CR8 до CR15 и от DR8 до DR15); или
- с использованием одного из унифицированных байтовых регистров SPL, BPL, SIL или DIL.
И не может использоваться при использовании AH, CH, BH или DH. (Префикс REX вообще, даже без установленных битов, изменяет значение кодировки для AH на SPL и т. Д.)
(Инструкции с префиксом VEX (например, AVX и некоторые BMI / BMI2) ) или EVEX (AVX512) используют это вместо REX для дополнительных регистровых битов. 2-байтовый VEX может кодировать X / YMM8..15 как пункт назначения или первый источник, без необходимости использовать более широкий 3-байтовый префикс VEX.)
Во-вторых, кроме проблемы размера кода, есть ли другие проблемы, такие как (CACHE, CYCLE, ...), если мы используем регистры rN (r8, r9, r10, ... ) вместо других регистров?
Нет, только размер кода (и для некоторых процессоров общее количество префиксов) . ЦП с кэш-памятью uop в основном не подвержены непосредственному воздействию размера кода , но косвенные эффекты, такие как увеличение занимаемой площади I-кэша (и менее плотная упаковка кэша uop), все еще остаются проблемой. И, конечно, в больших масштабах, с большими двоичными файлами.
Но некоторые процессоры (особенно семейство Silvermont) медленно декодируют инструкции с более чем 3 префиксами, поэтому, например, любая инструкция SSSE3 / SSE4 с префиксом REX глохнет декодер . См. Микроарх Агнера Фога pdf . В Silvermont даже escape-байт опкода 0F
для 2-байтовых опкодов считается одним из 3 вместе с обязательными префиксами для кодирования инструкций SIMD.
401000: 66 0f 38 00 07 pshufb xmm0,XMMWORD PTR [rdi] # 3 prefixes before the 00 opcode
401005: 66 41 0f 38 00 00 pshufb xmm0,XMMWORD PTR [r8] # 4 prefixes
Последний будет слишком медленным в Silvermont. Впрочем, отлично подходит для других процессоров с ограничением в 3 префикса (некоторые AMD IIR C); только в семействе Silvermont байт 0F считается префиксом.
Основные процессоры Intel могут декодировать произвольное количество префиксов без остановки, с учетом только ограничений на количество байтов машинного кода, которое они могут просматривать за тактовый цикл на этапе предварительного декодирования, который находит границы между инструкциями, и на этапе основного декодирования, который превращает до 5 команд (или более с помощью макро-синтеза) в до 5 мопов. (Skylake) Один из них имеет ограничение длины 16 байтов за цикл; IIR C это предварительное декодирование; проверьте руководство Агнер Фог, если это имеет значение.