Страницы

Поиск по вопросам

воскресенье, 1 декабря 2019 г.

Что такое “Прогрев JIT”?

#c_sharp


В статьях на хабре встретил в комментариях упоминание о так называемом "Прогреве JIT".

Что это такое?
    


Ответы

Ответ 1



JIT означает Just In Time, то есть "точно вовремя". JIT-компиляция транслирует байт-код виртуальной машины в машинный код физической машины именно в тот момент, когда он требуется в первый раз. (Это в частности значит, что если метод ни разу не вызывался за время работы программы, он не транслируется.) Метод, единожды скомпилированный, остаётся в памяти (кешируется) и при последующих вызовах выполняется сразу. Соответственно при старте программы JIT-компиляция выполняется довольно часто, а по мере работы — всё реже и реже. В целом, программа начинает выполняться быстрее. Такое поведение и позволяет говорить о «прогреве».

Ответ 2



Дело в том что JIT комипиляторы имеют свойство оптимизировать выполняемый код если он выполняется часто. При нескольких прогонах одной и той же функции или метода, JIT старается оптимизировать эту функцию для наиболее быстрого выполнения. Возможно вы замечали что в Java приложениях, что в .NET - только-только запущенная программа, работает медленнее чем та, которая уже какое-то время отработала. Естественно это при условии что корректно работают сборщики мусора и нет утечек памяти.

Ответ 3



Обычно имеется в виду следующее. Когда вы загружаете программу (по которой не пробежался AOT-компилятор, наподобие ngen), каждый метод представлен в виде IL-кода. При этом в текущей версии .NET нет функциональности интерпретации IL-кода, IL-код должен бють скомпилирован в нативный код. Функция в памяти содержит заглушку, которая вызывает JIT-компилятор, который компилирует IL-код в нативный код, и заменяет тело функции на этот нативный код. Таким образом, первое исполнение функции всегда длится дольше, чем последующие. В контексте измерения производительности это может быть нежелательно, тогда перед измерением проводят прогрев: выполняют функцию один раз. После этого нативный код сгенерирован, и функция будет выполняться быстро. Обратите внимание, что описанное поведение есть лишь особенность реализации в текущей версии майкрософтовской реализации .NET. Даже с этой версией приложение может быть скомпилировано AOT-компилятором, и в JIT-компиляция (а следовательно, и прогреве) более не будет необходимости. Даже сейчас можно скомпилировать приложение под .NET Native, и приложение не будет содержать IL-кода вовсе. Также, в будущих версиях стратегия JIT-компилятора имеет право поменяться. Например, он может компилировать не один метод зараз, а целый класс, пространство имён или вообще сборку. Или он может собирать статистику и улучшать код инкрементально, как это делает HotSpot. Поэтому не полагайтесь на это поведение.

Комментариев нет:

Отправить комментарий