Вопросы по оптимизации компилятора

  1. Какими способами компилятор устраняет повторяющиеся повторные вычисления подвыражений? Как вы отслеживаете подвыражения? И как определить повторяющиеся?
  2. Помимо использования побитовых операторов, какие методы снижения прочности обычно используют компиляторы?

person unj2    schedule 06.05.2009    source источник
comment
Вы должны разделить этот вопрос на две части и исправить заголовок. (у меня пока нет сил).   -  person Paul Biggar    schedule 30.07.2009


Ответы (5)


  1. Я полагаю, что многие компиляторы используют SSAPRE (статическое частичное устранение избыточности с одним назначением) для устранения повторяющихся выражений. Для этого требуется, чтобы код был в форме SSA, что позволяет проводить множество дополнительных оптимизаций.

  2. Я не совсем уверен в этом, но взгляните на этот список проходов LLVM. LLVM — это оптимизирующий IR для компиляторов, который зачастую даже быстрее, чем GCC. К каждому проходу есть небольшое пояснение. Если вам нужна дополнительная информация, посмотрите исходный код LLVM для этих проходов. Он написан на C++, но достаточно чист и понятен.

Редактировать: кстати, если вы разрабатываете компилятор, я настоятельно рекомендую LLVM, он очень прост в использовании и генерирует оптимизированный код.

person Zifre    schedule 06.05.2009
comment
ВАУ Спасибо. Эти ссылки были действительно полезны. - person unj2; 06.05.2009
comment
Определенно согласен с LLVM. Мы используем его в моей исследовательской группе. Здорово. - person Jay Conrod; 06.05.2009
comment
Не рекомендую SSAPRE. Для этого требуется HSSA, который ваш компилятор почти наверняка не предоставит. - person Paul Biggar; 30.07.2009

Для 1 имя оптимизации, которую вы ищете, — устранение общего подвыражения (CSE). В зависимости от вашего представления это может быть довольно легко. Обычно компилятор будет иметь некое промежуточное представление программы, в котором операции максимально разбиты и линеаризованы. Так, например, выражение c = a * b + a * b можно разбить следующим образом:

v1 = a * b
v2 = a * b
c = v1 + v2

Таким образом, вы можете выполнять CSE на очень низком уровне, ища операции с одним и тем же оператором и операндами. Когда вы сталкиваетесь с дубликатом (в данном случае v2), вы заменяете все его экземпляры оригиналом. Таким образом, мы могли бы упростить приведенный выше код:

v1 = a * b
c = v1 + v1

Обычно это предполагает, что вы назначаете каждую переменную только один раз (одна форма статического назначения), но вы можете реализовать что-то подобное без этого ограничения. Это становится более сложным, когда вы пытаетесь выполнить эту оптимизацию между ветвями. Как упоминает Zifre, посмотрите на устранение частичной избыточности.

В любом случае вы получаете некоторое базовое улучшение, и все, что вам нужно отслеживать, — это базовые выражения. Возможно, вы захотите пойти дальше и поискать арифметические тождества. Например, a * b совпадает с b * a. Кроме того, x * (y + z) = x * y + x * z. Это усложняет вашу оптимизацию, и неясно, даст ли это вам такое значительное улучшение производительности. Как ни странно, большая часть преимуществ от оптимизации CSE исходит от вычислений адресов, таких как доступ к массиву, и вам не понадобятся сложные идентификаторы, подобные приведенным выше.

Что касается версии 2, полезность уменьшения прочности действительно зависит от архитектуры, для которой вы компилируете. Обычно это просто включает в себя преобразование умножения и деления в сдвиги, сложения и вычитания.

person Jay Conrod    schedule 06.05.2009
comment
что, если повторяющиеся не находятся в одном и том же выражении? Например, x= a * b и где-то внизу y = a* b. Могу ли я каким-то образом обнаружить повторение a*b? - person unj2; 06.05.2009
comment
Хотя это повтор. В этом случае вы замените все будущие использования y на x. - person Jay Conrod; 06.05.2009

Я настоятельно рекомендую две печатные ссылки по этим темам:

  1. Проектирование и реализация расширенного компилятора Стивена С. Мучника
  2. Создание оптимизирующего компилятора Роберта Моргана

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

person Lance Richardson    schedule 06.05.2009

Чтобы добавить еще одну книгу в список рекомендаций, проверьте " Восторг хакера" Генри С. Уоррена. Это отличный сборник методов оптимизации общих операций, таких как преобразование целочисленных делений в умножения.

person Mike G.    schedule 07.05.2009

Вы ищете устранение частичной избыточности (PRE). И CSE (из других ответов), и движение кода, не зависящее от цикла, включены в PRE. (Разновидностью PRE является Lazy Code Motion, который я считаю оптимальным).

Ознакомьтесь с заметками лекций Кейта Купера, которые, кажется, описывают техники очень хорошо.

НЕ используйте SSAPRE. Насколько мне известно, для этого требуется особая форма SSA, известная как HSSA, которая имеет несколько недостатков:

  • Это довольно сложно
  • Для этого требуется глобальная нумерация значений (поэтому SSAPRE не обеспечивает нумерацию значений, поскольку ожидается, что она уже существует).
  • Он ничего не дает, если ваш язык не поддерживает указатели на переменные стека (а если поддерживает, прекратите писать собственный анализ и используйте LLVM или gcc).
  • gcc некоторое время использовал HSSA, но они отошли от него.
  • LLVM экспериментировал с ним, но, насколько мне известно, они его больше не используют.

РЕДАКТИРОВАТЬ:

В книге Мучника есть подробное описание, ссылка на которое есть в другом ответе.

person Paul Biggar    schedule 30.07.2009
comment
Знаете ли вы, почему GCC отошел от HSSA и почему LLVM решил не использовать его? Текущие версии GCC (7.0) помечают переменные VDEF и VUSE, для меня это похоже на HSSA. Вы не знаете, связаны ли они? - person paulotorrens; 08.05.2017
comment
Извините, это было давно, и я не участвовал. Я вообще ничего не помню об этом :( - person Paul Biggar; 09.05.2017
comment
Знай это чувство, братан. - person paulotorrens; 09.05.2017