Современная x86 модель стоимости - PullRequest
30 голосов
/ 31 марта 2012

Я пишу JIT-компилятор с бэкэндом x86 и изучаю ассемблер x86 и машинный код на ходу. Я использовал ARM ассемблер около 20 лет назад, и меня удивляет разница в стоимости моделей между этими архитектурами.

В частности, доступ к памяти и ответвления являются дорогостоящими в ARM, но эквивалентные операции стека и переходы дешевы в x86. Я полагаю, что современные процессоры x86 выполняют гораздо более динамическую оптимизацию, чем ядра ARM, и мне трудно предвидеть их последствия.

Какую модель стоит учитывать при написании ассемблера для x86? Какие комбинации инструкций являются дешевыми, а какие - дорогими?

Например, мой компилятор был бы проще, если бы он всегда генерировал длинную форму для загрузки целых чисел или перехода к смещениям, даже если целые числа были небольшими или близкие смещения, но это повлияло бы на производительность?

Я еще не делал с плавающей точкой, но я хотел бы перейти к нему в ближайшее время. Есть ли что-то неочевидное во взаимодействии нормального и плавающего кода?

Я знаю, что есть много ссылок (например, Майкла Абраша) на оптимизацию x86, но у меня есть предчувствие, что что-либо более чем несколько лет не подойдет для современных процессоров x86, потому что они сильно изменились за последнее время. Я прав?

Ответы [ 6 ]

35 голосов
/ 31 марта 2012

Лучшим справочником является Руководство по оптимизации Intel , в котором содержится довольно подробная информация об архитектурных опасностях и задержках команд для всех последних ядер Intel, а также множество примеров оптимизации.

Другим превосходным справочным материалом является Ресурсы оптимизации Agner Fog , которые также позволяют охватывать ядра AMD.

Обратите внимание, что модели с конкретными затратами по своей природе специфичны для микроархитектуры.Нет такой вещи, как «модель стоимости x86», которая имела бы какой-либо реальный смысл.На уровне инструкций характеристики производительности Atom дико отличаются от i7.

Я также хотел бы отметить, что доступ к памяти и ее ветви на самом деле не «дешевы» на ядрах x86 - это простоМодель исполнения ордеров стала настолько сложной, что может успешно скрывать их стоимость во многих простых сценариях.

5 голосов
/ 02 апреля 2012

Torbjörn Granlund Задержки команд и пропускная способность для процессоров AMD и Intel x86 тоже хороши.

Редактировать

Документ Гранлунда касается пропускной способности команд в контексте того, сколько инструкцийопределенного типа может быть выдан за такт (т. е. выполняется в параллель).Он также утверждает, что документация Intel не всегда точна.

3 голосов
/ 21 мая 2012

Сколько бы это ни стоило, раньше была удивительная книга под названием "Внутренние петли" Рика Бута , в которой подробно описывалось, как вручную оптимизировать микро сборку IA-86код для процессоров Intel 80486, Pentium, Pentium Pro и Pentium MMX, с множеством полезных реальных примеров кода (хеширование, перемещение памяти, генерация случайных чисел, сжатие Хаффмана и JPEG, умножение матриц).

К сожалению,Эта книга не обновлялась с момента ее первой публикации в 1997 году для более новых процессоров и архитектур процессоров.Тем не менее, я бы порекомендовал его как краткое введение в такие темы, как:

  • , какие инструкции, как правило, очень дешевые или дешевые, а какие не являются
  • , регистры которых являютсянаиболее универсальный (то есть не имеет никакого специального значения / не является регистром некоторых команд по умолчанию)
  • как объединять команды в пару, чтобы они выполнялись параллельно без остановки одного конвейера
  • различные виды остановок
  • прогноз ветвления
  • что следует иметь в виду в отношении кешей процессора
1 голос
/ 08 августа 2016

Конечно, отчеты Agner Fog и Справочное руководство по оптимизации архитектур Intel® 64 и IA-32 являются необходимыми и отличными справочными материалами. У AMD также есть руководство по оптимизации:

  • Руководство по оптимизации программного обеспечения для процессоров AMD Family 15h

Однако два инструмента Intel необходимы для понимания последовательностей кода:

* * 1010 Анализатор кода архитектуры Intel® Intel® VTune ™

IACA - ваша модель затрат. Я использую его на OSX, но VTune работает только на Windows и Linux.

Вы также можете изучить патентную литературу Intel и различные документы Intel, чтобы лучше понять, как все это работает:

  • Микроархитектура Intel Core следующего поколения
  • Haswell: процессор Intel Core четвертого поколения
  • Кэш микроопераций: интерфейс с поддержкой питания для переменной длины инструкции ISA
1 голос
/ 23 июня 2016

Стоит посмотреть на бэкэнды существующих компиляторов с открытым исходным кодом, таких как GCC и LLVM.У них есть модели стоимости обучения, а также приличные (но идеализированные) модели машин (например, ширина выпуска, размеры кэша и т. Д.).

0 голосов
/ 08 августа 2016

Я пишу JIT-компилятор с бэкэндом x86 и изучаю ассемблер x86 и машинный код на ходу.

Существенная проблема здесь заключается в том, что JIT-компилятор не может себе позволитьтратить огромное количество времени на микрооптимизацию.Поскольку «оптимизация» происходит во время выполнения, затраты на выполнение оптимизаций должны быть меньше, чем время, сэкономленное оптимизациями (в противном случае оптимизация становится чистой потерей производительности).

Для 80x86 существует несколько различныхПроцессоры с другим поведением / характеристиками.Если вы примете во внимание конкретные характеристики процессора, стоимость оптимизации возрастет, и вы сразу столкнетесь с барьером «стоит больше, чем вы получите».Это особенно верно для таких вещей, как «идеальное планирование инструкций».

К счастью, большинство (но не все) современных 80x86 процессоров имеют различные функции (неупорядоченный, спекулятивное выполнение, гиперпоточность) для смягчения (некоторые из) затраты производительности, вызванные "неидеальной" оптимизацией.Это приводит к тому, что дорогие оптимизации становятся менее выгодными.

Первое, что вы захотите сделать, - это определить, какие части кода следует оптимизировать, а какие - нет.Вещи, которые выполняются не часто (например, код инициализации «выполняется только один раз»), вообще не должны быть оптимизированы.Это только часто исполняемые фрагменты (например, внутренние циклы и т. Д.), Которые стоит побеспокоить.Как только вы определили часть, которая стоит оптимизировать, вопрос становится «сколько?».

Как грубое чрезмерное обобщение;Я ожидаю, что (в среднем) 90% кода вообще не стоит оптимизировать, а для 9% кода стоит только выполнить некоторую общую оптимизацию.Оставшиеся 1% (которые могли бы извлечь выгоду из обширной оптимизации в теории) в конечном итоге станут слишком большими хлопотами для разработчика JIT-компилятора на практике (и приведут к огромному кошмару сложности / проверяемости - например, «ошибки», которые существуют только тогда, когдаработает на некоторых процессорах "сценариев).

...