
Исследователь аппаратного обеспечения под ником Кристофер Домас (aka xoreaxeaxeax) представил проект «деоптимизации ЦП». В рамках решения разработчик решил найти самую медленную отдельную инструкцию x86, а также создал «зал позора» (Assembly Hall of Shame) — худшая из инструкций (fxrstor64) выполняет 198 миллиардов циклов за 62 секунды.
Для оптимизации работы программного обеспечения на аппаратном обеспечении анализ задержки инструкций рассматривает время, необходимое для выполнения низкоуровневых инструкций на процессоре, либо для оптимизации архитектуры, либо для оптимизации приложений для работы на конкретной архитектуре. Домас использует другой подход в своей таблице лидеров среди инструкций, которая направлена не на максимально быстрое выполнение инструкций ассемблера, а на максимально медленное, чтобы измерить производительность единственной инструкции с наибольшей задержкой.
Победителем здесь стала инструкция fxrstor64, выполнение которой заняло 62 секунды, или более 198 миллиардов циклов. Эта инструкция восстанавливает состояние регистров, используемых для SIMD-вычислений, в 512-байтовую ячейку памяти. Чтобы достичь наивысшего (самого медленного) результата, Домас сначала использовал свой собственный инструмент mmiotic для поиска области с высокой задержкой во внутренней сети PCIe, а затем заставил процессор загрузить 512-байтовое состояние из MMIO (Memory-Mapped I/O), по сути, обрабатывая все эти 512 байт как можно медленнее. На это потребовалось 74 миллиарда циклов, или чуть более 23 секунд. Затем Домас пошёл дальше, используя серию 4-байтовых операций чтения из другого регистра MMIO с высокой задержкой, перегружая root complex PCIe процессора и заставляя восстановление состояния ставиться в очередь за ненужными операциями чтения. Следующий шаг — использование инструкций AMX, доступных в Intel Sapphire Rapids для xrstore64. Область состояний увеличена с 512 байт до 8 КБ, что может привести к зависанию инструкции более чем на 1 триллион циклов.
Таблица лидеров для x86 уже доступна на GitHub, и, похоже, Домас планирует также создать таблицы лидеров для ARM и RISC-V. Для проведения тестов действуют несколько правил. Домас говорит, что подходит любая конфигурация, если оценивается только выполнение одной инструкции. Инструкции, прерываемые системой, не допускаются, как и эмулированные инструкции, выполняемые в обработчике. Все времена нормализованы относительно базовой тактовой частоты процессора, и все платформы тестировались без аппаратных модификаций. Здесь мы имеем дело с ассемблерным кодом, поэтому рейтинг зависит не столько от конкретной инструкции, сколько от того, что с ней делается.
Для тестирования Домас использовал в основном два процессора: Intel Core i7-8559U и AMD Ryzen 7 5800H (Trigkey S5). Однако для инструкции rdmsr они использовали чип VIA Eden, серию встраиваемых процессоров начала 2000-х годов. Команда rdmsr используется для чтения регистра, специфичного для модели, или MSR. По словам Домаса, VIA «использует недокументированный регистр по адресу 0x133, который обеспечивает невероятно высокое время отклика». Выполнение этой команды заняло 202 микросекунды или 161 602 цикла.
Это не первая попытка разработчика поэкспериментировать с низкоуровневыми инструкциями. Более ранний проект, называемый movfuscator, представляет собой компилятор C, который использует исключительно команду mov (перемещение).
Первые места рейтинга самых медленных инструкций x86 от Домаса с конца:
-
nop (ничего не делает) — 1 цикл 0 наносекунд.
-
nop16. Стратегия: обычная команда nop оказалась слишком короткой, но как сделать так, чтобы ничего не занимало больше времени? Попробуем longnnnnng nop. Процессор Intel(R) Core(TM) i7-8559U @ 2.70GHz, «data16 data16 data16 data16 data16 data16 data16 nopl 0x00000000(%%eax,%%eax,1)»: 20 циклов, 7 наносекунд.
-
rdtsc (просто справочная инструкция для ориентира): 49 циклов, 18 наносекунд.
Источник: habr.com