В прошлый раз мы разобрали два уровня компиляции: Tier0 — быстрый и неоптимизированный, и Tier1 — оптимизированный, для горячих методов. Но между ними прячется ещё одна стадия❗️
Возьмём наш однострочник
hello world, завернём его в метод Hello() для удобства измерений и запустим один раз. В сводке JIT будет одна строка:Program:Hello() [Tier0]
Один вызов — один дешёвый заход на Tier0, и программа кончилась. А теперь позовём тот же метод в цикле много раз:
Program:Hello() [Tier0]
Program:Hello() [Instrumented Tier0]
Program:Hello() [Tier1]
🕵️ Что за Instrumented Tier0?
Это тот же неоптимизированный Tier0, но со встроенными счётчиками. Пока метод работает на нём, рантайм записывает статистику: сколько раз метод вызвали, какие ветки чаще срабатывают, какие типы приходят в вызовы. Такая статистика — это профиль работы метода, а сам сбор называется профилированием
Дальше, на стадии Tier1, JIT оптимизирует метод с учётом профиля его работы, чтобы ускорить его наиболее горячие точки, а не просто делать это наугад
Такая оптимизация называется PGO — Profile-Guided Optimization, и по умолчанию она включена с .NET8
⏱️ Почему до Tier1 теперь два этапа
В прошлом посте я говорил про порог в 30 вызовов между Tier0 и Tier1. Если быть
DOTNET_TieredPGO=0). То есть в более свежих версиях фреймворка путь до Tier1 стал в два раза дольше из-за появления ещё одной стадии, которая длится так же примерно 30 вызовов (ну или смотря что у тебя указано в DOTNET_TC_CallCountThreshold)Первые 30 вызовов — это обычный Tier0, без особых оптимизаций. На 31-м метод перекомпилируется в Instrumented Tier0, на котором начинает собирать профиль работы метода. Инструментированная версия работает ещё 30 вызовов, и только потом метод компилируется на Tier1 — уже с оптимизациями по профилю. Мотивация простая: чтобы оптимизировать по профилю, профиль сначала надо собрать🧠
🅰️ Что с этим делать
🟢 В релизных сборках кода начиная с .NET8 профилирование включено по умолчанию
🟢 Профилирование позволяет более точно ускорить горячий код: JIT оптимизирует его по реальному поведению
🟢 Прогрев до Tier1 стал дольше: профилю нужно накопиться
А зависит ли этот путь от каких-нибудь факторов? Конечно! Но об этом расскажу в следующем посте 👉
🧑💻dp🥁
#dotnet #csharp #инженерныештучки #heavywednesday
