Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Pandangan mendalam tentang JIT dalam PHP 8

Pandangan mendalam tentang JIT dalam PHP 8

青灯夜游
青灯夜游ke hadapan
2022-04-25 20:46:533718semak imbas

Artikel ini akan membawa anda memahami JIT dalam PHP 8 dan bercakap tentang cara JIT mengambil bahagian dalam proses tafsiran saya harap ia akan membantu semua orang.

Pandangan mendalam tentang JIT dalam PHP 8

Pengkompil JIT (Just In Time) PHP 8 akan disepadukan ke dalam PHP sebagai sambungan Opcache digunakan untuk menukar opcode tertentu ke dalam arahan cpu pada masa jalan.

Ini bermakna selepas menggunakan JIT, Zend VM tidak perlu mentafsir opcode tertentu dan arahan ini akan dilaksanakan terus sebagai arahan peringkat CPU.

JIT PHP 8

Impak pengkompil PHP 8 Just In Time (JIT) tidak boleh dipertikaikan. Tetapi setakat ini, saya mendapati bahawa sangat sedikit yang diketahui tentang perkara yang JIT sepatutnya lakukan.

Selepas banyak penyelidikan dan berputus asa, saya memutuskan untuk menyemak sendiri kod sumber PHP. Menggabungkan beberapa pengetahuan saya tentang bahasa C dan semua maklumat bertaburan yang saya kumpulkan setakat ini, saya telah menghasilkan artikel ini, yang saya harap akan membantu anda memahami JIT PHP dengan lebih baik.

Ringkasnya: Apabila JIT berfungsi seperti yang diharapkan, kod anda tidak dilaksanakan melalui Zend VM, tetapi secara langsung sebagai satu set arahan peringkat CPU.

Itulah idea keseluruhannya.

Tetapi untuk memahaminya dengan lebih baik kita perlu mempertimbangkan cara php berfungsi secara dalaman. Tidak terlalu rumit, tetapi memerlukan beberapa pengenalan.

Saya menulis catatan blog yang memberikan gambaran umum tentang cara php berfungsi. Jika anda rasa siaran ini terlalu banyak, semak yang lain dan kembali kemudian. Perkara akan menjadi lebih mudah untuk difahami.

Bagaimana kod PHP dilaksanakan

Seperti yang kita sedia maklum, PHP ialah bahasa yang ditafsirkan, tetapi apakah maksud ayat ini?

Setiap kali kod PHP (skrip baris arahan atau aplikasi WEB) dilaksanakan, ia mesti melalui penterjemah PHP. Yang paling biasa digunakan ialah penterjemah PHP-FPM dan CLI.

Tugas jurubahasa adalah mudah: terima kod PHP, tafsirkannya dan kembalikan hasilnya.

Bahasa yang ditafsir secara umum mengikuti proses ini. Sesetengah bahasa mungkin menghapuskan beberapa langkah, tetapi idea umum adalah sama. Dalam PHP, prosesnya adalah seperti berikut:

  • membaca kod PHP dan mentafsirkannya sebagai satu set kata kunci yang dipanggil Token. Proses ini membolehkan penterjemah mengetahui kod yang telah ditulis dalam setiap program. Langkah ini dipanggil Lexing atau Tokenizing.

  • Selepas mendapat koleksi Token, jurubahasa PHP akan cuba menghuraikannya. Pokok sintaks abstrak (AST) dijana melalui proses yang dipanggil Penghuraian. Di sini AST ialah satu set nod yang mewakili operasi yang perlu dilakukan. Sebagai contoh, "gema 1 1" sebenarnya bermaksud "cetak hasil 1 1" atau lebih khusus "cetak operasi, operasi ini ialah 1 1".

  • Dengan AST lebih mudah untuk memahami operasi dan keutamaan. Menukar pepohon sintaks abstrak kepada operasi yang boleh dilaksanakan oleh CPU memerlukan ungkapan peralihan (IR), yang dalam PHP kita panggil Opcodes. Proses menukar AST kepada Opcodes dipanggil kompilasi .

  • Dengan Opcodes, inilah bahagian yang menyeronokkan: melaksanakan kod! PHP mempunyai enjin yang dipanggil Zend VM, yang mampu menerima satu siri Opcode dan melaksanakannya. Selepas semua Opcodes dilaksanakan, Zend VM menamatkan program.

Rajah ini boleh menjadikannya lebih jelas untuk anda:

Pandangan mendalam tentang JIT dalam PHP 8

Versi ringkas gambaran keseluruhan proses tafsiran PHP.

Seperti yang anda boleh lihat. Berikut ialah soalan: Walaupun kod PHP tidak berubah, adakah proses ini masih akan diikuti setiap kali ia dilaksanakan?

Mari kita lihat semula Opcodes. Betul! Itulah sebabnya sambungan Opcache wujud.

Pelanjutan Opcache

Pelanjutan Opcache disertakan dengan PHP dan biasanya tidak perlu melumpuhkannya. Apabila menggunakan PHP adalah lebih baik untuk menghidupkan Opcache.

Apa yang dilakukannya ialah menambahkan lapisan cache kongsi memori pada Opcodes. Tugasnya adalah untuk mengekstrak Opcode yang baru dijana daripada AST dan cachenya supaya langkah Lexing/Tokenizing dan Parsing boleh dilangkau semasa pelaksanaan.

Ini ialah gambar rajah proses yang merangkumi sambungan Opcache:

Pandangan mendalam tentang JIT dalam PHP 8

Proses tafsiran PHP menggunakan Opcache. Jika fail telah dihuraikan, PHP akan mendapatkan Opcodes cache untuknya dan bukannya menghuraikannya semula.

Melangkau langkah Lexing/Tokenizing, Parsing dan Compile dengan sempurna?.

Nota sampingan: Inilah PHP 7.4 Pramuat Ciri RFC yang hebat Membolehkan anda memberitahu PHP FPM untuk menghuraikan pangkalan kod, menukarnya kepada Opcodes dan cache sebelum melaksanakannya.

Adakah anda ingin tahu bagaimana JIT mengambil bahagian dalam proses tafsiran ini? Artikel ini akan menerangkan.

Apakah kesan kompilasi Just In Time?

Selepas mendengar siaran PHP dan JIT Zeev di PHP Internals News, saya mengetahui apa yang JIT sebenarnya lakukan.

Jika sambungan Opcache menjadikannya lebih pantas untuk mendapatkan Opcodes terus ke Zend VM, JIT membenarkannya berjalan tanpa menggunakan Zend VM sama sekali.

Zend VM ialah program yang ditulis dalam C yang bertindak sebagai lapisan antara Opcodes dan CPU. JIT menjana kod terkumpul secara langsung pada masa jalan, jadi PHP boleh melangkau Zend VM dan dilaksanakan terus oleh CPU. Secara teori, prestasi akan menjadi lebih baik.

Ini kedengaran pelik kerana pelaksanaan konkrit perlu ditulis untuk setiap jenis struct sebelum ia boleh disusun menjadi kod mesin. Tetapi sebenarnya ini adalah munasabah.

JIT PHP menggunakan pustaka yang dipanggil DynaASM (Dynamic Assembler), yang memetakan satu set arahan CPU dalam format tertentu ke dalam kod pemasangan untuk pelbagai jenis CPU. Oleh itu, pengkompil hanya perlu menggunakan DynASM untuk menukar Opcodes kepada kod mesin untuk struktur tertentu.

Namun, ada masalah yang menyusahkan saya sejak sekian lama.

Jika pramuat boleh menghuraikan kod PHP ke dalam Opcodes sebelum pelaksanaan, dan DynASM boleh menyusun Opcodes ke dalam kod mesin (Kompilasi Just In Time), mengapa kita tidak menggunakan kompilasi Ahead of Time) Bagaimana pula dengan menyusun PHP serta merta?

Salah satu sebab yang saya dapati dengan mendengar siaran Zeev ialah PHP ialah bahasa yang ditaip lemah, yang bermaksud PHP selalunya tidak mengetahui jenis pembolehubah sehingga Zend VM cuba untuk laksanakan opcode.

Anda boleh menyemak jenis kesatuan nilai Zend untuk mengetahui bahawa banyak penunjuk menunjuk kepada pembolehubah jenis yang berbeza. Apabila Zend VM cuba mendapatkan nilai daripada Zend_value, ia menggunakan makro seperti ZSTR_VAL untuk mendapatkan penuding kepada rentetan dalam jenis kesatuan.

Sebagai contoh, pengendali Zend VM ini mengendalikan ungkapan "kurang daripada atau sama dengan" (

Menggunakan kod mesin untuk melaksanakan logik inferens jenis tidak boleh dilaksanakan dan mungkin menjadi lebih perlahan.

Menilai dahulu dan kemudian menyusun juga bukan pilihan yang baik kerana menyusun kepada kod mesin ialah tugas intensif CPU. Jadi menyusun segala-galanya semasa runtime juga tidak bagus.

Jadi, bagaimanakah kompilasi Just In Time berfungsi

Sekarang kita tahu bahawa jenis tidak boleh disimpulkan dengan baik untuk disusun lebih awal. Kami juga tahu bahawa kompilasi pada masa jalan adalah mahal dari segi pengiraan. Jadi apakah faedah JIT untuk PHP?

Untuk mencari keseimbangan, JIT PHP cuba menyusun hanya Opcode yang berharga. Untuk melakukan ini, JIT menganalisis Opcodes yang Zend VM akan laksanakan dan menyemak kemungkinan kompilasi. (Mengikut fail konfigurasi)

Apabila Opcode disusun, ia akan menyerahkan pelaksanaan kepada kod yang disusun itu dan bukannya kepada Zend VM. Ia kelihatan seperti ini:

Pandangan mendalam tentang JIT dalam PHP 8

Proses tafsiran JIT PHP. Jika disusun, Opcodes tidak dilaksanakan oleh Zend VM.

Oleh itu, dalam sambungan Opcache, terdapat dua arahan pengesanan untuk menentukan sama ada untuk menyusun Opcode. Jika ya, pengkompil akan menggunakan DynASM untuk menukar Opcode ini kepada kod mesin dan melaksanakan kod mesin ini.

Menariknya, memandangkan terdapat had MB (juga boleh dikonfigurasikan) pada kod yang disusun dalam antara muka semasa, pelaksanaan kod mesti boleh bertukar dengan lancar antara JIT dan kod yang ditafsirkan.

Sebenarnya, ceramah oleh Benoit Jacquemont tentang JIT dalam php ini membantu saya memahami keseluruhan perkara ini.

Saya masih tidak pasti bila bahagian kompilasi dilakukan dengan berkesan, tetapi saya rasa sekarang saya tidak begitu mahu tahu.

Jadi, peningkatan prestasi anda mungkin tidak besar

Saya harap kini jelas mengapa kebanyakan aplikasi php tidak mendapat keuntungan prestasi yang besar daripada menggunakan penyusun tepat masa. Inilah sebabnya Zeev mengesyorkan bahawa pemprofilan dan percubaan dengan konfigurasi JIT yang berbeza untuk aplikasi anda adalah pendekatan terbaik.

Jika anda menggunakan PHP FPM, adalah perkara biasa untuk berkongsi kod opkod yang disusun merentas berbilang permintaan, tetapi itu masih bukan pengubah permainan.

Ini kerana JIT mengoptimumkan operasi yang intensif secara pengiraan dan kebanyakan aplikasi php hari ini lebih terikat kepada I/O daripada yang lain Jika anda mengakses cakera atau rangkaian, maka kendalikan Tidak kira sama ada operasi disusun atau tidak. Masa akan sangat serupa.

Melainkan...

Anda melakukan sesuatu yang tidak terikat dengan I/O, seperti pemprosesan imej atau pembelajaran mesin. Apa-apa sahaja yang tidak menyentuh I/O akan mendapat manfaat daripada pengkompil JIT.

Inilah sebabnya orang sekarang mengatakan bahawa kami lebih suka menulis fungsi asli dalam PHP daripada menulis dalam C. Jika fungsi ini dikompilasi pula, overhed akan menjadi tidak nyata.

Masa yang menyeronokkan menjadi pengaturcara PHP...


Saya harap artikel ini akan membantu anda dan membolehkan anda memahami JIT PHP8 dengan lebih baik.


Alamat asal: https://thephp.website/en/issue/php-8-jit/

Disyorkan: "Video PHP Tutorial

Atas ialah kandungan terperinci Pandangan mendalam tentang JIT dalam PHP 8. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Artikel ini dikembalikan pada:learnku.com. Jika ada pelanggaran, sila hubungi admin@php.cn Padam