0Pricing
PHP Academy · درس

ترجمة OPcache وJIT

سرّع PHP باستخدام التخزين المؤقت للـ bytecode وJIT

ترجمة OPcache وJIT درس مجاني في PHP Academy على CoddyKit. هذا هو الدرس 3 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في PHP Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة PHP Academy 4 دروس في المجموع.

تخزين الترجمة مؤقتًا

يخزّن OPcache تعليمات opcodes المترجمة في الذاكرة المشتركة، ولذلك تتجاوز PHP التحليل المعجمي والتحليل النحوي والترجمة في كل طلب. وإضافة إلى ذلك، يترجم JIT (منذ PHP 8.0) تعليمات opcodes الساخنة إلى شيفرة آلة أصلية. ويشكّل الاثنان معًا العمود الفقري لأداء PHP.

يغطي هذا الدرس إعداد OPcache والتحميل المسبق وضبط JIT.

ما الذي يفعله OPcache

تُخزَّن op_array المترجمة لكل ملف في مقطع من الذاكرة المشتركة تستخدمه جميع عمال FPM. ويعيد الطلب الذي يعثر على النسخة المخزّنة استخدام تعليمات opcodes مباشرة. كما ينفّذ OPcache محسّنًا (طيّ الثوابت، وإزالة التعليمات البرمجية الميتة، ودمج تعليمات opcodes) في أول مرة يترجم فيها الملف.

; Core OPcache config (php.ini)
opcache.enable = 1
opcache.memory_consumption = 256      ; MB of shared memory
opcache.interned_strings_buffer = 16  ; MB for interned strings
opcache.max_accelerated_files = 20000 ; cap on cached scripts

التحقق من الطوابع الزمنية

يحدّد validate_timestamps ما إذا كان OPcache سيعيد التحقق من أوقات تعديل الملفات. في بيئة التطوير، أبقوه مفعّلًا مع ضبط revalidate_freq على فترة قصيرة؛ أما في الإنتاج، فاضبطوه على 0 كي لا تفحص PHP الملفات مطلقًا، وانشروا التغييرات عبر مسح ذاكرة التخزين المؤقت (أو إعادة بناء الصورة).

; Production: never re-stat files
opcache.validate_timestamps = 0

; Development: check every 2 seconds
; opcache.validate_timestamps = 1
; opcache.revalidate_freq = 2

فحص ذاكرة التخزين المؤقت

يعرض opcache_get_status() معدل الإصابة، واستخدام الذاكرة، والبرامج النصية المخزّنة مؤقتًا؛ بينما يعرض opcache_get_configuration() الإعدادات. وتشير نسبة الإصابة المنخفضة أو عمليات إعادة التشغيل المتكررة إلى قلة الذاكرة أو كثرة الملفات.

<?php
if (function_exists('opcache_get_status')) {
    $s = opcache_get_status(false);
    if ($s) {
        printf("hits:   %d\n", $s['opcache_statistics']['hits']);
        printf("misses: %d\n", $s['opcache_statistics']['misses']);
        printf("hit %%: %.2f\n", $s['opcache_statistics']['opcache_hit_rate']);
        printf("used:   %.1f MB\n", $s['memory_usage']['used_memory'] / 1048576);
    } else {
        echo "OPcache enabled but no status (likely CLI)\n";
    }
} else {
    echo "OPcache not available\n";
}
?>

التحميل المسبق

يترجم التحميل المسبق (PHP 7.4 فأحدث) مجموعة من الفئات والدوال مرة واحدة عند بدء تشغيل الخادم، ويبقيها في الذاكرة بشكل دائم، بحيث تصبح متاحة لكل طلب من دون تحميل تلقائي أو ربط في كل طلب. وجّهوا opcache.preload إلى برنامج نصي يستدعي الملفات المطلوبة لتدفئة الذاكرة المؤقتة.

; php.ini
opcache.preload = /app/preload.php
opcache.preload_user = www-data

كتابة برنامج نصي للتحميل المسبق

يعمل برنامج التحميل المسبق في العملية الرئيسية. استخدموا opcache_compile_file() لتحميل الفئات من دون تنفيذها، أو استخدموا require ببساطة. تنشئ أُطر العمل قائمة تحميل مسبق؛ وهذا هو شكل إحداها.

<?php
// preload.php — runs once at startup
$dir = '/app/src';
$rii = new RecursiveIteratorIterator(
    new RecursiveDirectoryIterator($dir)
);

foreach ($rii as $file) {
    if ($file->getExtension() === 'php') {
        // Compiles + links the class into shared memory
        opcache_compile_file($file->getPathname());
    }
}
?>

دخول JIT

حتى مع تخزين تعليمات opcodes مؤقتًا، تظل الآلة الافتراضية تفسّرها. يترجم JIT تسلسلات تعليمات opcodes الساخنة إلى تعليمات أصلية للمعالج، متجاوزًا تكلفة توزيع الآلة الافتراضية. ويكون التحسن كبيرًا في الشيفرة الرقمية المقيّدة بالمعالج، ومتواضعًا في تطبيقات الويب المعتادة المقيّدة بالإدخال والإخراج (التي تقضي وقتها في قاعدة البيانات والشبكة، لا في المعالج).

إعداد JIT

يعمل JIT داخل OPcache، ولذلك يجب أن يكون OPcache مفعّلًا. يخصّص opcache.jit_buffer_size مساحةً لشيفرة الآلة المولّدة (وتعطّل القيمة 0 JIT). أما opcache.jit فهو وضع من أربعة أرقام يتحكم في استراتيجية التشغيل والتحسين.

; Enable JIT (requires opcache.enable=1)
opcache.jit_buffer_size = 128M
opcache.jit = tracing        ; alias for 1254, the common default

; The 4 digits CRTO mean:
;   C - CPU optimization flags
;   R - register allocation
;   T - trigger (when to JIT)
;   O - optimization level

JIT بالتتبّع مقابل JIT للدوال

توجد استراتيجيتان: JIT للدوال (الوضع 1205)، الذي يترجم الدوال كاملةً عند أول استدعاء؛ وJIT بالتتبّع (1254، وهو الاسم المستعار الافتراضي tracing)، الذي يحلّل التنفيذ ويترجم الحلقات والمسارات الساخنة، وغالبًا ما يحقق نتائج أفضل لأنه يخصص الشيفرة وفق الأنواع المرصودة. ويُعد التتبّع الإعداد الافتراضي الموصى به.

; Tracing JIT (recommended) — compiles hot traces
opcache.jit = tracing

; Function JIT — compiles entire functions when first called
; opcache.jit = function

; Disable JIT but keep opcode cache
; opcache.jit_buffer_size = 0

قياس أثر JIT

يتألق JIT في الحلقات الرقمية الضيقة. وهذا الاختبار المعياري المستقل (حلقة داخلية شبيهة بحساب ماندلبروت) يمثل نوع حمل العمل المقيّد بالمعالج الذي يمكن أن يقلل JIT زمن تنفيذه بدرجة كبيرة؛ شغّلوه مع jit_buffer_size وبدونه للمقارنة.

<?php
function mandelEscape(float $cr, float $ci, int $max): int {
    $zr = 0.0; $zi = 0.0; $n = 0;
    while ($n < $max && ($zr * $zr + $zi * $zi) <= 4.0) {
        $t  = $zr * $zr - $zi * $zi + $cr;
        $zi = 2.0 * $zr * $zi + $ci;
        $zr = $t;
        $n++;
    }
    return $n;
}

$start = hrtime(true);
$sum = 0;
for ($y = 0; $y < 200; $y++) {
    for ($x = 0; $x < 200; $x++) {
        $sum += mandelEscape($x / 100 - 2, $y / 100 - 1, 256);
    }
}
printf("sum=%d  time=%.2f ms\n", $sum, (hrtime(true) - $start) / 1e6);
?>

متى لا تتوقعوا مكاسب

في طلب نموذجي يستعلم من قاعدة بيانات، ويعرض قالبًا، ويعيد JSON، لا ينفّذ المعالج الكثير من العمليات الحسابية الخام؛ لذلك قد يمنح JIT مكاسب لا تتجاوز بضعة بالمئة أو لا يمنح أي مكاسب. أعطوا الأولوية أولًا لـOPcache والتحميل المسبق والاستخدام الجيد لقاعدة البيانات وذاكرة التخزين المؤقت. واقصروا ضبط JIT على معالجة الصور والرياضيات والمحللات البرمجية وغيرها من الشيفرات كثيفة الحساب.

تحقّق سريع

ما الذي يمنحكم إياه التحميل المسبق ولا توفره ذاكرة OPcache المؤقتة العادية؟

مراجعة

يخزّن OPcache op_arrays المترجمة في الذاكرة المشتركة وينفّذ محسّنًا؛ اضبطوا validate_timestamps=0 في بيئة الإنتاج، واضبطوا حجم memory_consumption/max_accelerated_files بشكل مناسب. يبقي التحميل المسبق الفئات المختارة مقيمةً في الذاكرة عند بدء التشغيل. ويترجم JIT (داخل OPcache، ويتطلب jit_buffer_size) الشيفرة الساخنة إلى تعليمات أصلية — محققًا مكاسب كبيرة في الرياضيات المقيّدة بالمعالج، وقليلة في تطبيقات الويب المقيّدة بالإدخال والإخراج. استخدموا opcache_get_status() للتحقق.

الأسئلة الشائعة

هل درس «ترجمة OPcache وJIT» مجاني؟

نعم — نص درس «ترجمة OPcache وJIT» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة PHP Academy، انتقل إلى CoddyKit PRO. تتضمن دورة PHP Academy 4 دروس في المجموع.

ماذا ستتعلم في «ترجمة OPcache وJIT»؟

سرّع PHP باستخدام التخزين المؤقت للـ bytecode وJIT تتمرن على PHP Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.

هل أحتاج إلى خبرة سابقة لأبدأ PHP Academy؟

لا تُشترط خبرة سابقة. PHP Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 3 من أصل 4.

كم من الوقت يستغرق درس «ترجمة OPcache وJIT»؟

معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.

هل يمكنني كتابة وتشغيل أكواد في درس PHP Academy هذا؟

نعم. كل درس في PHP Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.

جميع الدروس في هذه الدورة

  1. كيف تعمل Zend Engine
  2. إدارة الذاكرة وجمع البيانات المهملة
  3. ترجمة OPcache وJIT
  4. كتابة إضافة PHP أساسية بلغة C
← العودة إلى PHP Academy