Bosh sahifa Wiki JIT

JIT

JIT — dastur kodi yoki bytecode’ni bajarilish paytida native machine code’ga aylantiradigan compilation usuli. Uning to‘liq nomi Just-In-Time Compilation hisoblanadi.

JIT interpreter tez startupi bilan oldindan compile qilingan native kod performance’i o‘rtasida muvozanat yaratadi. Runtime dastur qanday ishlayotganini kuzatib, eng ko‘p bajariladigan qismlarni optimallashtiradi.

Ishlash modeli

Oddiy jarayon:

  1. Dastur bytecode yoki oraliq kodda yuklanadi.
  2. Dastlab interpreter orqali bajarilishi mumkin.
  3. Runtime method va looplar necha marta ishlatilganini kuzatadi.
  4. “Issiq” kod JIT compilerga beriladi.
  5. Native code yaratiladi.
  6. Keyingi chaqiriqlar native versiyaga yo‘naltiriladi.

Bu tiered compilationning umumiy ko‘rinishi.

Hot code

Tez-tez bajariladigan function, method yoki loop hot code deb ataladi.

Runtime counter yoki sampling orqali uni aniqlaydi.

Har kodni darhol kuchli optimization bilan compile qilish qimmat. Sovuq kod interpreterda yoki tez, kam optimizatsiyali compilerda qolishi mumkin.

Tiered compilation

JIT bir nechta darajada ishlashi mumkin:

Dastur uzoq ishlasa, muhim kod yuqori darajaga ko‘tariladi.

Bu startup va uzoq muddatli performance’ni muvozanatlashtiradi.

Runtime profiling

AOT compiler barcha real inputni oldindan bilmaydi.

JIT esa runtime’da quyidagilarni kuzatadi:

  • object type;
  • branch qaysi tomonga ko‘p ketadi;
  • method target;
  • loop count;
  • allocation;
  • exception;
  • call frequency.

Bu ma’lumot asosida spekulyativ optimization bajariladi.

Inlining

Method chaqiruvi o‘rniga uning kodi caller ichiga qo‘yiladi.

Afzalliklari:

  • call overhead kamayadi;
  • keyingi constant propagation;
  • dead code elimination;
  • type specialization

imkoniyati paydo bo‘ladi.

Juda ko‘p inlining code size va instruction cache bosimini oshiradi.

Devirtualization

Virtual method chaqirig‘i runtime profilingda doim bitta type’ga tegishli bo‘lsa, JIT uni to‘g‘ridan-to‘g‘ri chaqiriqqa aylantirishi mumkin.

Bu inliningni ham ochadi.

Agar keyin boshqa type paydo bo‘lsa, spekulyatsiya bekor qilinadi.

Deoptimization

JIT taxmin asosida optimizatsiya qiladi.

Masalan, variable doim integer bo‘ladi deb hisoblaydi. Keyin boshqa type keladi.

Runtime:

  • optimizatsiyalangan koddan chiqadi;
  • interpreter yoki kam optimizatsiyali kodga qaytadi;
  • state’ni tiklaydi;
  • kerak bo‘lsa qayta compile qiladi.

Bu deoptimization deb ataladi.

On-stack replacement

Uzoq loop interpreterda boshlangan bo‘lishi mumkin. Loop tugashini kutmasdan JIT bajarilishni optimizatsiyalangan kodga ko‘chiradi.

Bu On-Stack Replacement deb ataladi.

Benchmark warm-up jarayonida muhim.

Code cache

JIT hosil qilgan machine code maxsus xotira hududida saqlanadi.

Code cache:

ga ega.

Cache to‘lsa yangi methodlar JIT qilinmasligi yoki eski kod chiqarilishi mumkin.

W^X

Xavfsizlik uchun memory page bir vaqtda writable va executable bo‘lmasligi kerak.

JIT avval sahifaga kod yozadi, keyin permissionni executable qiladi.

Ba’zi platforma signed JIT, entitlement yoki maxsus API talab qiladi.

Startup xarajati

JIT compilerning o‘zi CPU va memory ishlatadi.

Dastlab:

xarajati mavjud.

Qisqa umrli CLI dasturda AOT yoki interpreter tezroq umumiy natija berishi mumkin.

Warm-up

Dastur boshlanganda hali hot code aniqlanmagan va optimized native code yo‘q.

Bir necha takrorlashdan keyin performance yaxshilanadi.

Benchmark JIT warm-upni hisobga olmasa noto‘g‘ri xulosa beradi.

Pause

Ba’zi JIT compilation application thread’da, boshqasi background compiler threadda bajariladi.

Compilation CPU contention yaratishi mumkin.

Latency-sensitive tizimda compiler threadlari va optimization darajasi nazorat qilinadi.

JIT va garbage collection

JIT object layout, write barrier va safepointlarni bilishi kerak.

GC objectlarni ko‘chirsa, compiled code reference’lari yangilanadi yoki handle orqali ishlaydi.

JIT stack map yaratib, qaysi register va stack slot object reference ekanini ko‘rsatadi.

Safepoint

Runtime thread holatini aniq ko‘ra oladigan nuqta safepoint.

GC, deoptimization yoki profiling uchun threadlar safepointga kelishi mumkin.

Uzoq loop safepoint tekshiruvisiz bo‘lsa, stop-the-world kechikadi.

JIT va AOT

Jihat JIT AOT
Compile vaqti Runtime Build yoki install
Profil ma’lumoti Haqiqiy workload Oldindan yoki profil fayli
Startup Compilation xarajati bor Odatda tezroq
Peak performance Yuqori bo‘lishi mumkin Barqaror
Code portability Bytecode tarqatish mumkin Targetga xos artifact
Runtime murakkabligi Yuqori Kamroq

Ko‘p platforma JIT va AOTni birga ishlatadi.

Profile-guided optimization

Oldingi ishga tushishdan profiling ma’lumoti yig‘ilib, keyingi compile’da ishlatilishi mumkin.

Bu AOTga JITga o‘xshash real workload ma’lumotini beradi.

Dynamic holat o‘zgarsa profil eskirishi mumkin.

Diagnostika

JIT muammosida:

tekshiriladi.

Peak performance sekin bo‘lsa faqat source code emas, JIT qanday machine code yaratgani ham ko‘riladi.

Inline cache

Dynamic method yoki property lookup natijasi call site yonida cache qilinishi mumkin. Monomorphic inline cache bitta type’ni, polymorphic cache bir nechta type’ni eslab qoladi. Juda ko‘p turli type keladigan megamorphic joyda cache samarasi pasayadi va runtime umumiy lookup yo‘liga qaytadi.

Bog‘liq tushunchalar

Just-In-Time Compilation, Bytecode, Interpreter, AOT, Runtime profiling, Inlining, Deoptimization, Code cache, Safepoint, Virtual machine