Есть ли компилятор точно в срок для скомпилированных языков, таких как C и C ++? (Первые имена, которые приходят на ум, это Clang и LLVM! Но я не думаю, что они в настоящее время поддерживают это.)
Объяснение:
Я думаю, что программное обеспечение могло бы выиграть от обратной связи профилирования во время выполнения и агрессивно оптимизированной перекомпиляции горячих точек во время выполнения, даже для скомпилированных в машину языков, таких как C и C ++.
Оптимизация по профилю выполняет аналогичную работу, но с той разницей, что JIT будет более гибким в разных средах. В PGO вы запускаете свой бинарный файл до его выпуска. После того, как вы выпустили его, он не будет использовать обратную связь среды / ввода, собранную во время выполнения. Таким образом, если шаблон ввода изменяется, это является пробой к снижению производительности. Но JIT хорошо работает даже в таких условиях.
Однако я считаю, что это спорный кастрированный баран ЛТ компиляции выигрыш в производительности перевешивает свои собственные накладные расходы.
источник
Ответы:
[Смотрите историю изменений для совершенно другого ответа, который сейчас в основном устарел.]
Да, есть пара JIT-компиляторов для C и / или C ++.
CLing (как вы можете догадаться из игры) основан на Clang / LLVM. Он действует как переводчик. То есть вы даете ему некоторый исходный код, даете команду для его запуска, и он запускается. Основное внимание здесь уделяется удобству и быстрой компиляции, а не максимальной оптимизации. Таким образом, хотя технически это и есть ответ на сам вопрос, это на самом деле не очень подходит для намерения ОП.
Другая возможность - NativeJIT . Это подходит к вопросу несколько иначе. В частности, он не принимает исходный код C или C ++, а компилирует и выполняет его. Скорее, это небольшой компилятор, который вы можете скомпилировать в вашу C ++ программу. Он принимает выражение, которое в основном выражается как EDSL внутри вашей программы на C ++, и генерирует из этого фактический машинный код, который вы затем можете выполнить. Это намного лучше подходит для фреймворка, в котором вы можете скомпилировать большую часть своей программы с помощью обычного компилятора, но у вас есть несколько выражений, о которых вы не узнаете до времени выполнения, которые вы хотите выполнить с тем, что приближается к оптимальной скорости выполнения.
Что касается очевидной цели первоначального вопроса, я думаю, что основной смысл моего первоначального ответа остается в силе: в то время как JIT-компилятор может адаптироваться к таким вещам, как данные, которые варьируются от одного выполнения к другому или даже динамически изменяются в течение одного выполнения, реальность такова, что это имеет относительно небольшое значение, по крайней мере, как общее правило. В большинстве случаев, запуск компилятора во время выполнения означает, что вам нужно отказаться от некоторой оптимизации, поэтому самое лучшее, на что вы обычно надеетесь, это то, что он близок к скорости, которую может дать обычный компилятор.
Хотя можно постулировать ситуации, когда информация, доступная для JIT-компилятора, могла бы позволить ему генерировать существенно лучший код, чем обычный компилятор, случаи этого на практике кажутся довольно необычными (и в большинстве случаев, когда я был в состоянии проверить это произошло, на самом деле это было связано с проблемой в исходном коде, а не со статической моделью компиляции).
источник
Да, есть JIT-компиляторы для C ++. С точки зрения производительности, я думаю, что Оптимизация по профилю (PGO) все еще лучше.
Однако это не означает, что JIT-компиляция еще не используется на практике. Например, Apple использует LLVM в качестве JIT для своего конвейера OpenGL. Это домен, где у вас есть значительно больше информации во время выполнения, которую можно использовать для удаления большого количества мертвого кода.
Еще одним интересным приложением JIT является Cling, интерактивный интерпретатор C ++, основанный на LLVM и Clang: https://root.cern.ch/cling
Вот пример сеанса:
Это не игрушечный проект, но он фактически используется в CERN, например, для разработки кода для Большого адронного коллайдера.
источник
C ++ / CLI соединяется. Конечно, C ++ / CLI не C ++, но он довольно близок. Тем не менее, Microsoft JIT не делает супер умных / симпатичных оптимизаций на основе поведения во время выполнения, о которых вы спрашиваете, по крайней мере, насколько мне известно. Так что это действительно не помогает.
http://nestedvm.ibex.org/ превращает MIPS в байт-код Java, который затем соединяется. Проблема с этим подходом из вашего вопроса состоит в том, что вы выбрасываете много полезной информации к тому времени, когда она попадает в JIT.
источник
Во-первых, я предполагаю, что вы хотите использовать jit для трассировки, а не метод jit.
Лучшим подходом было бы скомпилировать код в llvm IR, затем добавить код трассировки, прежде чем создавать собственный исполняемый файл. Как только блок кода становится достаточно хорошо используемым, и как только достаточно информации о значениях (а не о типах, как в динамических языках) переменных, собирается, код может быть перекомпилирован (из IR) со средствами защиты, основанными на значениях переменных.
Кажется, я помню, что был достигнут некоторый прогресс в создании ac / c ++ jit в clang под именем libclang.
источник