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

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

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

[[Պատկեր:Dynamic compilation types.png|thumb|upright=2.10| Դինամիկ կոպիլյացիայի դասկարգումները]]

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

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

[[Պատկեր:Virtual machine scheme.png|thumb|upright=2.50 | Վիիտուալ մեքենայի միջավայրը՝ միջանկյալ ծրագրի բեռնման համար]]
Լեզուներում, ինչպիսին են [[Java]], [[PHP]], [[C|C#]],[[Lua]], [[Perl]], [[GNU CLISP]], [[Ելակետային կոդ|սկզբնական կոդը]] թարգմանվում է միջանկյալ նկարագրության ([[անգլ.]] intermediate representation )՝ **բայթկոդ** անվանմամբ ([[անգլ.]] bytecode)։ Բայթկոդը ինչ-որ կոնկրետ պրեցոսսորի մեքենայական կոդ չի հանդիսանում և կարող է տեղափոխվել համակարգչի տարբեր ճարտարապետություն և իրականացվել նույն ձևով։ Բայթկոդը ինտերպրետացվում է կամ իրականցվում ''վիրտուալ մեքենայում ''։ JIT կոպիլյատորը կարդում է բայթկոդի տարբեր բաժիներ (կամ ամբողջը միանգամից՝ հազվադեպ) և կոմպիլյացնում է մեքենայակն կոդի։ Այդ բաժիները կարող են լինել ֆայլեր, ֆունկցիաներ կամ կոդի ցանկացած հատված։ Կոդը կարող է կոմպիլյացված լինել, երբ այն պատրաստվում է կատարվել (այստեղից էլ ''"just-in-time"'' անունը)։ Մեկ անգամ կոմպիլյացված կոդը կարող է կեշավորվել և հետագայում կրկին օգտագործվել առանց վերակոմպիլյացայի ([[անգլ.]] recompile)։

Ի տարբերություն, ավանդական ''ինտերպրետացված վիրտուալ մեքենան'' ([[անգլ.]] interpreted virtual machine) ուղղակի ինտերպրետացնում է բայթկոդ, սովորաբար ավելի ցածր արդյունավետությամբ։ Որոշ ինտերպրետատորներ նույնիսկ ինտերպրետացնում են սկզբնական կոդը, բայթկոդի առանց սկազբանական կոմպիլյացիայի քայլի և նույնիսկ ավելի վատ արդյունավետությամբ։ ''Ստատիկ կոմպիլյացված կոդը'' ([[անգլ.]] Statically compiled code) կամ հարազատ կոդը (անգլ. native code) կոմպիլյացվում է նախքան տեղակայումը։

JIT մեթոդի հիմանակն նպատակը՝ ստատիկ կոմպիլյացիայի արդյունավետությանը հասնելը և գերազանցելն է, այդպիսով պահպանելով դինամիկ կոմպիլյացիայի առավելությունները՝<div>
* Ծանրաքարշ գործողությունների մեծամասնությունը, ինչպիսին է նախնական կոդի վերլուծությունը և հիմնական օպտիմիզացիաները հաճախ մշակվում են կոմպիլյացիայի ժամանակ, մինչև տեղակայումը՝ բայթկոդից մեքենայական կոդի կոմպիլյացիան շատ ավելի արագ է, քան կոմպիլյացիան սկզբնական կոդից։ 
* Բայթկոդը փոխադրելի է, ի տարբերություն հարազատ կոդի կամ մեքենայական կոդի ()։ 
</div><div>
* Միջոցը կարող է հսկել բայթկոդի կատարումը կոմպիլյացիայից հետո, այդ պատճառով այն կարող է գործարկվել ավազամանում ( , Ավազամանը համակարգչային անվտանգությունում հատուկ մշակված միջոց է, համակարգչային ծրագրերի անվտանգ կատարման համար)։
* Պետք է նշել նաև որ հարազատ ծրագրերի համար ևս կա այդպիսի հնարավորություն, բայց տվյալ մեթոդի իրականցումը դժվար է։
</div><div>
* Կոմպիլյացիան բայթկոդից մեքենայակն կոդի հեշտ է իրականցնել, քանի որ օպտիմիզացիայի աշխատանքի մեծամասնությունը արդեն արված է եղել կոմպիլյատորի կողմից։ 
</div>

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

== **Մեկնարկի հապավումը և օպտիմիզացիաները** ==

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

Այլ օպտիմիզացիայի միջոց է կոմպիլյացնել հավելվածի այն հատվածները, որոնք ավելի հաճախ են օգտագործվում։ Այդ մոտեցում է իրականցված է SunMicrosystems ընկերության ''PyPy ''-ում и'' HotSpot Java Virtual Machine ''-ում։<div><br>
</div><div>Երբեմն բավական դժվար է գտնել ճիշտ փոխզիջումներ։ Այդպես, օրինակ ''Sun’s Java Virtual Machine-ը'' ունի երկու աշխատանքի ռեժիմ՝ կլիենտ և սերվեր ([[անգլ.]] client and server) ։ Կլիենտի ռեժիմում կոմպիլյացիայի քանակը և օպտիմիզացիան մինիմալ են ավելի արագ բեռնման համար, մինչդեռ սերվերի ռեժիմում հասնում է մաքսիմալ արդյունավետության, բայց դրա պատճառով մեծանում է բեռնման ժամանակը։</div><div><br>
</div><div>Եվս մեկ մեթոդ, որը կոչվում է ''pre-JIT '', կոդը կոմպիլյացնում է մինչև բեռնելը. տվյալ մեթոդի առավելությունը հանդիսանում է բեռնման ժամանակի արագությունը, մինչդեռ թերությունը հանդիսանում է վատ կոմպիլյացված կոդը ''runtime JIT ''-ի հետ համեմատած։<br>
</div>

== **Հուսալիությունը''' ==
Քանի որ JIT կոմպիլյացիան բաղկացած է սկզբնական կոդի տվյալներից առաջանում է հուսալության (անվտանգության) հարց։

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

## Արտաքին հղումներ
* Free Online Dictionary of Computing entry 
* libJIT 
* Mozilla Nanojit 
* SoftWire
* CCG
* Dyninst 
* JatoVM 
* AsmJit
* Xbyak 
* sljit 
* Profiling Runtime Generated and Interpreted Code using the VTune Performance Analyzer

Կատեգորիա:Ծրագրավորում