کامپایل درجا
کامپایل درجا (به انگلیسی: Just-in-time Compilation) در رایانش که به کامپایل پویا نیز معروف است، روشی است که زمان اجرای برنامههای کامپیوتری مبتنی بربایت کد (کد ماشین مجازی) را بهبود میدهد. از آن هنگام که بایت کد زبان ماشین را به زبان سطح بالاتر ترجمه میکرد؛ آن را کندتر از کد ماشین کامپایل میکرد. مگراینکه واقعاً به کد ماشین کامپایل میشد، تا میتوانست برنامه را قبل از آن یا در طول اجرای برنامه اجرا کند-ایجاد برنامه با سرعت بارگذاری کم-. در این مورد اخیر- که مبتنی برکامپایل به موقع است- برنامه درحافظه به عنوان بایت کد ذخیره میشود، اماقطعهای از کد قطعا به صورت مقدماتی برای اینکه برنامه سریعتر اجرا شود به کد ماشین کامپایل میشود. کامپایلرهایJIT مانند یک روش نزدیک پیوندی عمل میکنند، با ترجمهای که پیوسته صورت میگیرد، مانند مترجمان، اما با نهان کردن کد ترجمهشده برای به حداقل رساندن سرعت ایجاد آن. همچنین دیگر امتیازاتی که بر روی کدی که به صورت استاتیک کامپایل شدهاست را در زمان ویرایش پیشنهاد میدهد، مانند کنترل محدودیتهای انواع دادهها و توانایی تقویت امنیت قوانینی که صحت کار ماشین را تأیید میکند. JIT روی دو ایدهٔ اولیه در محیطهای زمان اجراساخته میشود: کامپایل بایت کد و کامپایل پویا. که این کد را پیش از زمان اجرا بهصورت طبیعی اجرا میکند، برای مثال تبدیل بایت کد به کد ماشین اصلی. چندین محیط اجرای جدید، مانند مایکروسافت. پایگاه دادهٔ نت و چندین اجراگرازجاوا، بر کامپایل بهموقع برای اجرای کد با سرعت بالا استناد میکند.
مرور
دریک سیستم کامپایل بایت کد، کد اصلی به یک ترکیب بیتهای هرکدام از کد حرفها ترجمه شدهاست. بایت کد کد ماشین برای هر کامپیوتر خصوصی نیست، و شاید بین معماریهای کامپیوتر قابل انتقال باشد. بایت کد شاید بعدازاین با ادامه دادن متن بدون توقف یک ماشین بالقوه تفسیرشود. کامپایلرJIT بایت کدها را در بسیاری از بخشها (یا نسبتاً همه آن را) میخوانند و آنها را به صورت پویا به زبان ماشین کامپایل میکنند تا برنامه بتواند سریعتراجرا شود. جاوابررسیهای زمان اجرا را در بخشهای مختلف کد انجام میدهد و این دلیل آن است که تمام کد یک بار کامپایل نمیشود. این کار میتواند هردفعه برای هر تابع یا حتی هر قطعه کد اختیاری صورت گیرد؛ کد میتواند وقتی که اجرامیشود کامپایل شود (از این جاست که اسم به موقع یا درجا میآید)، و سپس آن را نهان میکند و بازهم ازآن بدون نیازبه کامپایل مجدد استفاده میکند. برای مقایسه یک تفسیر قراردادی ماشین بالقوه با بایت کد به سادگی با اجراهایی کمتر تفسیرمیشود. برخی تفسیرها حتی برای تفسیر کد اصلی، بدون برداشت از اولین کامپایل به بایت کد، حتی با بدترین اجرا انجام میشوند. کد کامپایل شدهاستاتیک یا کد اصلی پیش از جایگزین شدن کامپایل میشود. یک محیط گردآوری پویا برای هر کامپایلر یکسان است که میتواند در طول اجرا استفاده شود. برای مثال، بیشتر سیستمهای متداول زبان پردازش لیسپ یک تابع کامپایل دارند که میتواند یک تابع جدید ایجاد شده در طول اجرای برنامه را کامپایل کند. همچنین میتواند کد اختصاصی پویایی را کامپایل کند و دربسیاری از سناریوها، مزایای اجراهای قابل توجه راروی کد کامپایل شدهٔ ناپویا فراهم کند. همچنین روی بسیاری از سیستمهای JIT این کاررا انجام دهد. یک هدف رایج از استفاده از تکنیکهای JIT رسیدن یا پیشی گرفتن در اجرای کامپایل استاتیک است، نگهداری مزایای تفسیر بایت کد:بیشتر از"سخت بالا آمدن" تجزیهٔ سورس کد اصلی وایجاد بهینهسازی پایهای اغلب در زمان کامپایل کنترل میشود، پیش از قرارگیری:کامپایل از بایت کد به کد ماشین سریعتر از کامپایل از سورس است. بایت کد قرار گرفته شده قابل انتقال است، مانند کد اولیه. چون زمان اجرا روی کامپایل کنترل میشود، مانند بایت کد تفسیر شده، که میتواند دریک فایل امن اجرا شود. کامپایلرها از بایت کد به کد ماشین برای نوشتن آسانتر هستند چون کامپایلر بایت کد قابل انتقال پیش از این بیشترکاررا پیش برده است. کد JIT در اصل اجرای بهتری از سایر مترجمان ارائه میدهد. علاوه بر این در بعضی موارد میتواند اجرای بهتری از کامپایل استاتیک پیشنهاد دهد، همچون بسیاری از بهینهسازیها که فقط در زمان اجرا عملی هستند: کامپایل میتواند برایCPU هدفمند و فراهم کردن مدل سیستمی که برنامه کاربردی را اجرا میکند بهینه باشد. برای مثال JITمیتواند بردار 2SSE را دستورالعملهایی کهCPU از آنها پشتیبانی میکرده را آشکار کند وانتخاب کند. اگرچه اخیراً هیچJIT فعالی وجود ندارد که از آن استفاده کند. برای به دست آوردن این سطح از بهینهسازی منحصراً با یک کامپایلر استاتیک، یک بخش باید یک متغیر دودویی را برای هر پایگاه/معماری یا شامل نسخههای چندگانهٔ بخشهایی از کد بدون یک سیگنال دودویی انجام دهد. سیستم درجمع آوری آمار و ارقام برای این که در واقع چگونه برنامه ران میشود در محیطی که در آن قرار دارد تواناست، و میتواند دوباره آن را ترتیب دهد و مجدداٌ آن را برای اجرای بهینه کامپایل کند. اگر چه، برخی کامپایلرهای استاتیک اطلاعات پروفایل را به عنوان ورودی میگیرند. سیستم میتواند بهرهبرداری از کد هدف را انجام دهد (برای مثال این لاین کردن تابعهای کتابخانه) بدون ازبین بردن فواید پیوستگی پویا و بدون اینکه اصل آن را برای کامپایلرهای استاتیک وسایر بخشهای متصل ازبین برد. به خصوص، هنگام انجام جانشین سازیهای این لاین هدف، یک کامپایل استاتیک آنچه را که برای بررسی زمان و حتمیکردن آن که یک فراخوانی بالقوه اتفاق میافتد اگر کلاس حقیقی ابطالهای شی روش این لاین لازم است رخ دهد، وبررسیهای شرط حد بر دسترسیهای آرایه ممکن است بدون حلقهها به پردازش نیاز داشته باشد. با کامپایل آنی در بسیاری موارد این پردازش میتواند بیرون از حلقهها حرکت کند، که اغلب افزایش سرعت را به همراه دارد. اگرچه ممکن است با استاتیک زبانهای جمعآوری شده دادههای ناخواسته نیز کامپایل شوند، یک سیستم بایت کد میتواند راحتتر کد اجرا را برای بهرهبرداری بهترازحافظه نهان مجدداً مرتب کند.
تاخیردر شروع و بهینهسازی آن
JIT معمولاً باعث یک تأخیر در اجرای اولیهٔ یک کاربرد، به اندازهٔ کافی برای زمان مقتضی برای ظرفیت و کامپایل بایت کد میشود. گاهی اوقات این تأخیر "تاخیر درزمان شروع" نامیده میشود. در اصل، بیشتردر بهینهسازیهای اجراهای JIT کد بهتر تولید میشود، اما تأخیر اولیه میتواند زیاد شود. در یک کامپایلرJIT باید یک معاوضه بین زمان کامپایل و کیفیت کدی که انتظار میرود به صورت خودکار تولید شود صورت گیرد. در هر حال، به نظر میرسد که بیشترشدن زمان شروع گاهی وظیفهٔ عملگرهایbound- IO را بیشتر از کامپایل JIT بالا میبرد. (برای مثال، فایل دادهای کلاس jar.rt برای ماشین بالقوه جاوا JVM،۴۰ مگابایت است وJVM دادههای زیادی را در این فایل بزرگ زمینهای جستجو میکند) یک بهینهسازی ممکن، استفاده از ماشین بالقوه جاواHOtSpOt، ترکیب تفسیر و کامپایل JIT است. کد نرمافزارتفسیراولیه است. اما هشداردهنده هایJVM که توالیهای بایت کد را انجام میدهد مکررانجام میشود و آنها را برای کد ماشین برای اجرای روان و مستقیم بر روی سختافزار ترجمه میکند. برای بایت کدی که فقط دفعات کمی اجرا میشود، زمان کامپایل را ذخیره میکند و تأخیر اولیه را کاهش میدهد: برای تکرار اجرای بایت کد، کامپایلJIT استفاده میشود برای اجرا در سرعت بالا، بعد از یک مرحلهٔ اولیه از تفسیر کند. علاوه براین، چون برای اجرای بخش کمتری از کدش زمان بیشتری میگذراند، زمان کامپایل کاهش یافته مهم است. سرانجام، در تفسیرکد اولیه، اجرای استاتیکها میتواند قبل از کامپایل جمعآوری شود، که برای ایجاد بهتربهینهسازی کمک میکند. احتمال درست میتواند برای وضعیتها قابل اجرا باشد. برای مثال، ماشین بالقوه جاوا دو روش اصلی دارد-مشتری و سرور. در روش مشتری، کامپایل کمینه و بهینهسازی، برای کاهش زمان شروع اجرا انجام میشود. در روش سرور، کامپایل دامنهدار و بهینهسازی انجام میشود، برای یکبار اجرای ماکسیمم نرمافزاری که توسط زمان اولیه از دست میرود اجرا میشود. دیگر کامپایلرهای به موقع در جاوا از یک محاسبهکننده زمان اجرا برای شمارش زمانهای یک روش ترکیب اجرایی همراه با اندازهٔ بایت کد یک روش غیرمستدل برای تصمیمگیری در خصوص کامپایل استفاده میکنند. هنوز عدهای شماری از زمانهای اجرایی ترکیب شده با کشف حلقهها را استفاده میکنند. در اصل، پیشبینی اینکه روشها برای بهینهسازی در کاربردهایی کوتاه اجرا از طولانی اجرا کدام بادقت تر است سخت است. مولد تصویر اصلی(Ngen)توسط مایکروسافت یکی دیگر از رویکردها در کاهش زمان اجرا است. کامپایلرهای اولیه Ngen (یا"JITهای اولیه ")بایت کد درتصویر یک زبان واسط میانی معمولی در کد اصلی ماشین. به عنوان یک نتیجه، هیچ کامپایل زمان اجرایی نیاز ندارد. شبکه نت ۲ با ویژوال استودیو ۲۰۰۵ ران میشود Ngenرابر همهٔ فایلهای DLLها کتابخانه مایکروسافت بعد از نصب جابه جا میکندjitting-pre یک روش برای بهبود زمان شروع فراهم میکند. اگرچه، کیفیت کد تولید شده ممکن است به خوبی یک ... نباشد، به همان دلیل که چرا کد کامپایل شده ناپویاست، بدون بهینهسازی سیستم پرسنلی ذخیره انبوه کامپیوتر، نمیتواند به خوبی کد کامپایل JIT در این مورد شدید: نبود داده برای سیستم پرسنلی کامپیوتر برای گرداندن آن، برای مثال، نهانسازی در خط. همین طور اینجا ابزارهای جاوا که برکامپایلر AOTهمراه با یک کامپایلرJET)JIT بالاتر) یا مترجم ترکیب شدهاند وجود دارد. (کامپایلرGNU برای جاوا)
تاریخچه
جدیدترین کامپایلرJIT منتشر شده در اصل به شبکه LISP توسط مک کارتی در ۱۹۶۰ تعلق دارد. درتابعهای بازگشتی مقاله اولیهٔ اوازبیانات نمادین و محاسبات آنها توسط ماشین، بخش اول، اوبه تابعهایی که در طول زمان اجرا ترجمه شدند اشاره میکند، به وسیلهٔ خودداری کردن از نیاز به ذخیره خروجی کامپایلر برای کارت پانچها. یک تکنیک مؤثر برای راه اندازی کد کامپایل شده از تفسیری که توسط میچل در سال ۱۹۷۰ پیش رفته بود، که او برای زبان آزمایشی ²C L به کار برد. اسمال تاک پیشگام بود در جنبههایی جدید از کامپایلهای جی ای تی. برای مثال، ترجمه برای کد ماشین در خصوص تقاضای آن، و نتیجه برای استفادهٔ بعدی نهان میشود. وقتی که حافظه کم شود، سیستم بعضی از این کد را حذف خواهد کرد و آن را بازیابی خواهد کرد وقتی که مجدداً به آن نیاز داشته باشد. زبان Self Sun´sاین تکنیکها را بهبود داد و در یک کلام سریعترین سیستم Smlltalk در جهان بود؛ دست یافتن به نصف سرعت بهینهC اما با یک زبان کاملاً شی گرا. تولید Sun توسط خود شرکت متوقف شده بود، اما تحقیقات به سمت زبان جاوا کشیده شد، و فعلاً توسط پیادهسازیهای زیادی از ماشین بنیادی جاوا استفاده میشود، مانند HOtSpOtکه بر مبنای آن ساخته شدهاست، و به صورت گسترده از پایهٔ این تحقیق استفاده میشود. پروژه Dynmo ،HP یک کامپایلرJIT آزمایشی بود که فرمت بایت کد و فرمت کد ماشین را که همان بود، سیستم به گردش درمی آورد کد ماشین -6000-HPAبه درون کد ماشین 8000-HPAبرخلاف شهود، این در تأمین برق بیوقفه نتیجه داشت، در برخی موارد از ۳۰ درصد از انجام این بهینهسازیهای اجازه داده شده در سطح کد ماشین، برای مثال، کد این لاین برای استفادهٔ بهترحافظهٔ نهان و بهینهسازیهای فراخوانیها برای کتابخانههای پویا و بسیاری از بهینهسازیهای زمان اجرا که کامپایلرهای قراردادی برای این منظور توانا نیستند.
جستارهای وابسته
منابع
- Aycock, John (2003). "A brief history of just-in-time". ACM Computing Surveys. 35 (2): 97–113. doi:10.1145/857076.857077. ISSN 0360-0300.
- Thompson, Ken (1968). "Programming Techniques: Regular expression search algorithm". Communications of the ACM. 11 (6): 419–422. doi:10.1145/363347.363387. ISSN 0001-0782.