JIT կոմպիլյացիա

JIT-կոմպիլյացիա (անգլ. Just-in-time compilation), դինամիկ կոմպիլացիան (անգլ. dynamic translation) ծրագրի կատարման ժամանակ արված կոմպիլյացիա է՝ այլ ոչ թե մինչև ծրագրի կատարումը։ Շատ հաճախ այն բաղկացած է մեքենայական կոդի թարգմանությունից, բայց կարող է վերաբերվել նաև այլ ֆորմատի թարգմանությանը։

JIT-կոմպիլյացիան մեքենայական կոդը թարգմանելու երկու ավանդական գաղափարների կոմբինացիա է՝ AOT-կոմպիլյացիա և ինտերպրետացիա, և իր մեջ համատեղում է երկուսի որոշ առավելություններ և թերություններ։ Կոպիտ ասած, JIT-կոմպիլյացիան համատեղում է կոմպիլյացված կոդի արագությունը ինտերպրետացիայի ճկունության հետ, ինտերպրետատորի հավելյալ ծախսերի հետ և լրացուցիչ կոմպիլյացիայի ծախսերը (ոչ միայն ինտերպրետացիայի)։ JIT-կոմպիլյացիան դինամիկ կոմպիլյացիայի տեսակ է, այդպիսով JIT-կոմպիլյացիայի տեսությունում կարող է տալ ավելի արագ կատարում քան ստատիկ կոմպիլացիան։ Ինտերպրետացիան և JIT-կոմպիլյացիան հատկապես համապատասխանում են դինամիկ ծրագրավորման լեզուների համար, այդ դեպքում runtime համակարգը կարող է կարգավորել late-bound տվյալների տիպերը և երաշխավորել կատարման անվտանգությունը։


== Իրականցման առանձնահատկությունները ==
JIT-կոմպիլյացիան կարող է կիրառվել ինչպես ամբողջ ծրագրում, այնպես էլ դրա առանձին մասերում։ Օրինակ տեքստային ձևախիչը (անգլ. text editor) կարող է կոմպիլյացնել ռեգուլյար արտահայտությունները տեքստի ավելի արագ փնտրման համար։ AOT-կոմպիլյացիայի հետ այդպիսի բան անել հնարավոր չէ, քանի որ տվյալները տրամադրում են ծրագրի կատարման ժամանակ, այլ ոչ թե կոմպիլյացիայի ժամանակ։


== Նկարագրություն ==

Լեզուներում, ինչպիսին են Java, PHP, C#,Lua, Perl, GNU CLISP, սկզբնական կոդը թարգմանվում է միջանկյալ նկարագրության (անգլ. intermediate representation )՝ բայթկոդ անվանմամբ (անգլ. bytecode)։ Բայթկոդը ինչ-որ կոնկրետ պրեցոսսորի մեքենայական կոդ չի հանդիսանում և կարող է տեղափոխվել համակարգչի տարբեր ճարտարապետություն և իրականացվել նույն ձևով։ Բայթկոդը ինտերպրետացվում է կամ իրականցվում վիրտուալ մեքենայում ։ JIT կոպիլյատորը կարդում է բայթկոդի տարբեր բաժիներ (կամ ամբողջը միանգամից՝ հազվադեպ) և կոմպիլյացնում է մեքենայակն կոդի։ Այդ բաժիները կարող են լինել ֆայլեր, ֆունկցիաներ կամ կոդի ցանկացած հատված։ Կոդը կարող է կոմպիլյացված լինել, երբ այն պատրաստվում է կատարվել (այստեղից էլ "just-in-time" անունը)։ Մեկ անգամ կոմպիլյացված կոդը կարող է կեշավորվել և հետագայում կրկին օգտագործվել առանց վերակոմպիլյացայի (անգլ. recompile)։
Ի տարբերություն, ավանդական ինտերպրետացված վիրտուալ մեքենան (անգլ. interpreted virtual machine) ուղղակի ինտերպրետացնում է բայթկոդ, սովորաբար ավելի ցածր արդյունավետությամբ։ Որոշ ինտերպրետատորներ նույնիսկ ինտերպրետացնում են սկզբնական կոդը, բայթկոդի առանց սկազբանական կոմպիլյացիայի քայլի և նույնիսկ ավելի վատ արդյունավետությամբ։ Ստատիկ կոմպիլյացված կոդը (անգլ. Statically compiled code) կամ հարազատ կոդը (անգլ. native code) կոմպիլյացվում է նախքան տեղակայումը։

JIT մեթոդի հիմանակն նպատակը՝ ստատիկ կոմպիլյացիայի արդյունավետությանը հասնելը և գերազանցելն է, այդպիսով պահպանելով դինամիկ կոմպիլյացիայի առավելությունները՝
JIT կոդը հիմանականում առաջարկում է ավելի լավ արդյունավետություն քան ինտերպրետատորը։ Դրանից բացի կարող է առաջարկել ավելի լավ արդյունավետություն քան ստատիկ կոմպիլյացիան, քանի որ շատ օպտիմիզացիաներ հնարավոր են միայն ծրագրի կատարման ժամանակ ՝

Կոմպիլյացիան կարող է իրականցվել անմիջապես նպատակային պրացեսսորի և օպերացիան համակարգի համար, որում գործարկվելու է հավելվածը։ Օրիանակ JIT-ը կարող է օգտագործել վեկտորային SSE2 պրոցոսսորի ընդլայնում, եթե գտնում է որ այդ պրոցեսսորը աջակցում է այն։ Սակայն մինչ դեռ JIT-ի հիմանակն իրականացում չկա, որտեղ այդ մոտեցումը կօգտագործվի, քանի որ պետք է օպտիմիզացիայի նման մակարդակ ապահովել, համեմատած ստատսիկ կոմպիլյատերի հետ, կպահանհանջվեր կամ ապպահովել բինար ֆայլ յուրաքանչյուր պալտֆորմի տակ, կամ միացնել օպտիմիզատորի մեկ գրադարան յուրաքանչյուր պալտֆորմի տակ։
Այդ միջոցը կարող է աշխատող ծրագրի մասին հավաքել վիճակագրություն և դուրս բերել օպտիմիզացիաներ հաշվի առնելով այդ ինֆորմացիաները։ Որոշ ստատիկ կոմպիլյատորներ կարող են նաև ընդունել մուտքային ինֆորմացիա։
Այդ միջոցը կարող է կատարել կոդի գլոբալ օպիմիզացիաներ (օրինակ՝ գրադարանային ֆունկցիաներ ներկառուցումը) առանց կորցնելու դինամիկ կոմպիլյացիայի առավելությունները և առանց հավելյալ ծախսերի՝ բնորոշ ստատիկ կոմպիլյատորին և լինկերին։
Կեշի ցանկալի օգտագործման համար կոդի ավելի հասարակ վերակառուցում։


== Մեկնարկի հապավումը և օպտիմիզացիաները ==
JJIT կոմպիլյատորի տիպիկ հապավման պատճառը ծախսերն են բեռնման և բայթկոդի կոմպիլյացիայի վրա։ Ընդհանուր դեպքում, ինչքան լավ և ինչքան մեծ օպտիմիզացիաներ է կատարում JIT-ը, այնքան երկար է ստանում հապաղումը։ Այդ պատճառով JIT կոմպիլյատորը պետք է փոխզիջումներ կատարի գեներացված կոդի որակի և մեկնարկի ժամանակի միջև։ Սակայն, հաճախ ստացվում է այնպես, որ նեղ տեղերը (անգլ. bottleneck) կոմպիլյացիայի գործընթացում ստացվում է ոչ ինքը՝ կոմպիլյացիայի գործընթացը, այլ մուտքային և ելքային հապավումները (ինչպես օրինակ, rt.jar-ը Java Virtual Machine-ում (JVM) ունի 40ՄԲ չափ, և իրենում մետատվյալների փնտրումը զբաղեցնում է բավականչափ շատ ժամանակ)։

Այլ օպտիմիզացիայի միջոց է կոմպիլյացնել հավելվածի այն հատվածները, որոնք ավելի հաճախ են օգտագործվում։ Այդ մոտեցում է իրականցված է SunMicrosystems ընկերության PyPy -ում и HotSpot Java Virtual Machine -ում։


== Հուսալիությունը ==
Քանի որ JIT կոմպիլյացիան բաղկացած է սկզբնական կոդի տվյալներից առաջանում է հուսալության (անվտանգության) հարց։
JIT կոմպիլյացիան իրենում համախմբում է սկզբնական կոդի կամ բայթկոդի կոմպիլյացիան մեքենայական կոդի և դրանց կատարումը։ Որպես կանոն արդյունքը գրվում է հիշողությունում և կատարվում է անմիջապես, չօգտագործելով դիսկ և չկանչելով առանձին ծրագիր։ Ժամանակակաից ճարտարապետությունում հուսալիությունը բարձրացնելու համար կամայական հիշողության հատվածները չեն կարող լինել իրականցված։ Ճիշտ աշխատանքի հաամար հիշողությունը պետք է նշված, որպես կատարվող (NX bit), ավելի մեծ անվտանգության համար ֆլագը պետք է դրված լինի հիշողության մեջ կոդի բեռնումից հետո, իսկ այդ հիշողությունը պետք է հասանելի լինի միայն ընթեցման համար։


== Հղումներ ==
Free Online Dictionary of Computing entry Archived 2002-09-05 at the Wayback Machine.
libJIT
Mozilla Nanojit Archived 2012-05-09 at the Wayback Machine.
SoftWire
CCG
Dyninst
JatoVM
AsmJit
Xbyak Archived 2016-01-12 at the Wayback Machine.
sljit
Profiling Runtime Generated and Interpreted Code using the VTune Performance Analyzer