JIT оптимизатор для C / C ++ - PullRequest
       22

JIT оптимизатор для C / C ++

5 голосов
/ 11 сентября 2011

Я читал о преимуществах JIT по сравнению с предварительно скомпилированным, и одним из упомянутых было то, что JIT мог корректировать прогнозы ветвления на основе фактических данных времени выполнения. Прошло много времени с тех пор, как я написал компилятор в колледже, но мне кажется, что нечто подобное может быть достигнуто и для предварительно скомпилированного кода и в большинстве случаев (где нет явных переходов).

Рассмотрим следующий код:

   test x
   jne L2:
L1: ...
   jmp L3:
L2: ...
L3:

Если у нас есть какие-то инструменты времени выполнения, которые видят, сколько раз 'jne L2' истинно, он мог бы физически поменять местами все инструкции в блоке L1: и блоке L2 :. Конечно, он должен знать, что ни один поток не находится ни в одном из блоков во время перестановки, но это детали ...

   test x
   jeq L1:
L2: ...
   jmp L3:
L1: ...
L3:

Я понимаю, что есть также проблемы, когда программный код загружается в постоянную память и т. Д., Но это идея.

Итак, мой вопрос: возможна ли такая оптимизация JIT для C / C ++, или я упускаю какую-то фундаментальную причину, почему это невозможно сделать? Существуют ли JIT-оптимизаторы для C / C ++?

Ответы [ 4 ]

8 голосов
/ 11 сентября 2011

Не существует JIT-компилятора для C ++, о котором я знаю;однако GCC поддерживает оптимизацию с обратной связью (FDO), которая может использовать профилирование во время выполнения для оптимизации прогнозирования ветвлений и т. п.

См. параметры GCC , начинающиеся с "-fprofile" (Подсказка:«-fprofile-use» использует сгенерированный профиль времени выполнения для выполнения оптимизации, а «-fprofile-generate» используется для создания профиля времени выполнения).

6 голосов
/ 11 сентября 2011

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


РЕДАКТИРОВАТЬ: Наибольшее преимущество в использовании JIT-компилятора заключается в таком коде.

if (debug) {
   // do something
}

JIT очень хороши для обнаружения и оптимизации кода, который ничего не делает. (Если у вас есть микро-тест, который предполагает, что Java намного быстрее, чем C, скорее всего, JIT обнаружил, что ваш тест ничего не делает, а компилятор C этого не сделал)

Вы можете спросить, почему у C нет чего-то подобного? Потому что есть что-то "лучшее"

#if DEBUG
    // do something
#endif

Это оптимально, если DEBUG редко изменяется, и у вас очень мало таких флагов, так что вы можете скомпилировать каждую полезную комбинацию.

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

Если у вас много таких флагов и нецелесообразно компилировать каждую комбинацию, вам нужно полагаться на предсказание ветвлений для динамической оптимизации кода.

1 голос
/ 11 сентября 2011

Вы обращаетесь к отслеживанию или повторной оптимизации JIT, а не просто к любому старому JIT, что-то подобное не было сделано для C или C ++ (по крайней мере, не публично).Тем не менее, вы можете захотеть проверить, не идет ли LLVM таким образом с веткой (учитывая, что это и компилятор, и JIT) с использованием внешних интерфейсов Clang или GCC, так как мне кажется, некоторые темы предполагают, что это может быть реализовано.

0 голосов
/ 11 сентября 2011

Двоичный перекомпилятор HP Dynamo продемонстрировал, что можно добиться ускорения до 20% оптимизированного кода, создаваемого компилятором C ++.Dynamo не является компилятором JIT, поскольку он начинается с произвольного машинного кода вместо некоторого представления более высокого уровня, такого как байт-код JVM или .NET CIL, но в принципе JIT для C ++ может быть только более эффективным, чем Dynamo.См .: http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.12.7138&rank=1

Dynamo был создан для архитектуры HP PA-RISC и никогда не предлагался в качестве коммерческого продукта, поэтому он не очень полезен в современном мире, где преобладают варианты x86.Интересно, работали ли когда-нибудь VMware, Connectix или Parallels с добавлением проходов оптимизации для своих перекомпиляторов, или они уже избавились от двоичного преобразования в пользу функций виртуализации в последних процессорах x86.

...