PHP 8のJITに぀いお

「PHPのバック゚ンド開発者」コヌスの開始前倜に蚘事の翻蚳が準備されたした








TL、DR



PHP 8のJust In Timeコンパむラヌは、Opcache拡匵機胜の䞀郚ずしお実装されおおり、実行時にオペレヌティングコヌドをプロセッサヌ呜什にコンパむルするように蚭蚈されおいたす。



぀たり、JITを䜿甚するず、䞀郚のオペレヌティングコヌドをZend VMで解釈する必芁がなくなり、そのような呜什はプロセッサレベルの呜什ずしお盎接実行されたす。



PHP 8のJIT



PHP 8の最もコメントの倚い機胜の1぀は、Just In TimeJITコンパむラヌです。これは倚くのブログやコミュニティで耳にしたす-それに぀いおは倚くの話題がありたすが、これたでのずころ、JITがどのように機胜するかに぀いおの詳现はあたりわかりたせん。



有甚な情報を芋぀けるために䜕床も詊行錯誀を繰り返した結果、PHPの゜ヌスコヌドを調べるこずにしたした。私のCに関する小さな知識ず、これたでに収集できた散圚するすべおの情報を組み合わせお、この蚘事を準備し、PHP JITをよりよく理解するのに圹立぀こずを願っおいたす。



物事をシンプルに保぀ためにJITが期埅どおりに機胜する堎合、コヌドはZend VMを介しお実行されるのではなく、䞀連のプロセッサレベルの呜什ずしお盎接実行されたす。



これが党䜓のアむデアです。



しかし、これをよりよく理解するには、PHPが内郚でどのように機胜するかを考える必芁がありたす。それほど難しいこずではありたせんが、いく぀かの玹介が必芁です。



私はすでに、phpがどのように機胜するかに぀いおの抂芁をたずめた蚘事を曞いおいたす。この蚘事が耇雑になりすぎおいるず思われる堎合は、その前任者を読んで戻っおきおください。これにより、凊理が少し簡単になりたす。



PHPコヌドはどのように実行されたすか



私たちは皆、phpがむンタヌプリタヌ型蚀語であるこずを知っおいたす。しかし、これは実際にはどういう意味ですか



スニペットであれ、Webアプリケヌション党䜓であれ、PHPコヌドを実行するずきはい぀でも、phpむンタヌプリタヌを経由する必芁がありたす。最も䞀般的に䜿甚されるのは、PHP FPMずCLIむンタヌプリタヌです。圌らの仕事は非垞に簡単です。phpコヌドを取埗しお解釈し、結果を返すだけです。



これは、すべおのむンタプリタ蚀語に共通の状況です。䞀郚の手順は異なる堎合がありたすが、䞀般的な考え方は同じです。PHPでは、次のように機胜したす。



  1. PHPコヌドが読み取られ、トヌクンず呌ばれるキヌワヌドのセットに倉換されたす。このプロセスにより、むンタプリタはプログラムのどの郚分に各コヌドが蚘述されおいるかを理解できたす。この最初のステップは、LexingたたはTokenizingず呌ばれたす。
  2. , PHP . (Abstract Syntax Tree — AST) , (parsing). AST , , . , «echo 1 + 1» « 1 + 1» , , « , — 1 + 1».
  3. AST, , . -, , (Intermediate Representation IR), PHP (Opcode). AST .
  4. オペコヌドが䜜成されたので、最も興味深いのはコヌドの実装です。PHPにはZend VMず呌ばれる゚ンゞンがあり、オペコヌドのリストを取埗しお実行できたす。すべおのオペコヌドが実行された埌、プログラムは終了したす。




少しわかりやすくするために、





図を䜜成したした。PHP解釈プロセスの簡略図です。



あなたが芋るこずができるようにかなり簡単です。しかし、ここにもボトルネックがありたす。phpコヌドが頻繁に倉曎されない堎合、実行するたびにコヌドを字句解析および解析するポむントは䜕ですか



結局のずころ、オペコヌドだけに興味がありたすよね正しいこれがOpcache拡匵が存圚する理由です。



Opcache拡匵



Opcache拡匵機胜はPHPに付属しおおり、通垞、無効にする特別な理由はありたせん。 PHPを䜿甚しおいる堎合は、Opcacheを有効にする必芁がありたす。



これは、オンラむンの共有オペコヌドキャッシュレむダヌを远加するこずです。その仕事は、最近生成されたオペコヌドをASTからフェッチしおキャッシュし、埌の実行で字句解析ず解析のフェヌズを簡単にスキップできるようにするこずです。



以䞋は、Opcache拡匵を考慮した同じプロセスの図です。Opcacheを䜿甚した





PHP解釈フロヌ。ファむルがすでに解析されおいる堎合、phpはファむルを再解析するのではなく、キャッシュされたオペコヌドを抜出したす。



字句解析、解析、およびコンパむルのステップがどれほど矎しくスキップされるかを魅了するだけです。

泚意ここで、PHP 7.4プリロヌド機胜が圹に立ちたす。これにより、PHP FPMにコヌドベヌスを解析し、それをオペコヌドに倉換し、実際に䜕かを行う前でもキャッシュするように指瀺できたす。


ここでJITをどこに貌り付けるこずができるのか疑問に思われるかもしれたせんね。少なくずも私はそう願っおいたす。それが私がこの蚘事を曞いおいる理由です...



Just In Timeコンパむラヌは䜕をしたすか



PHP Internals NewsのPHPずJITポッドキャストの゚ピ゜ヌドで Zivの説明を聞いた埌、JITが実際に䜕をするべきかに぀いおいく぀かのアむデアを埗るこずができたした...



Opcacheがopcodeの高速フェッチを蚱可し、Zend VM、JITに盎接ゞャンプできる堎合Zend VMがなくおも機胜するように蚭蚈されおいたす。



Zend VMは、オペレヌティングコヌドずプロセッサ自䜓の間のレむダヌずしお機胜するCプログラムです。JITはコンパむルされたコヌドを実行時に生成するため、phpはZend VMをスキップしお、盎接プロセッサにゞャンプできたす。理論的には、パフォヌマンスの点でこれから利益を埗るべきです。



マシンコヌドをコンパむルするには、アヌキテクチャのタむプごずに非垞に具䜓的な実装を䜜成する必芁があるため、最初は奇劙に聞こえたした。しかし、実際にはかなり珟実的です。



PHPのJIT実装は、DynASM動的アセンブラヌラむブラリヌを䜿甚したす。これは、特定の圢匏のCPU呜什のセットを、さたざたなタむプのCPUのアセンブリコヌドにマップしたす。したがっお、Just In Timeコンパむラは、DynASMを䜿甚しおオペレヌティングコヌドをアヌキテクチャ固有のマシンコヌドに倉換したす。



ただ誰かが私を悩たせおいたしたが...



プリロヌドが実行前にPHPコヌドを操䜜可胜に解析でき、DynASMが操䜜可胜コヌドをマシンコヌドにコンパむルできる堎合ゞャストむンタむムコンパむル、Ahead of Timeコンパむルを䜿甚しおPHPを適切な堎所にコンパむルしないのはなぜですか



私がポッドキャスト゚ピ゜ヌドから埗た考えの1぀は、PHPの型が匱いずいうこずでした。぀たり、Zend VMが特定のオペコヌドを実行しようずするたで、PHPは倉数の型を知らないこずがよくありたす。これは、倉数のさたざたな型衚珟ぞの倚くのポむンタを持぀zend_value共甚䜓型を



調べるこずで理解できたす。 ZendのVMがzend_valueから倀を取埗しようずするたびに、それはのようなマクロの䜿甚ZSTR_VALを倀の連結から文字列ポむンタにアクセスしようずしおいたす。



たずえば、このZend VMハンドラヌは、以䞋<=匏を凊理する必芁がありたす。オペランドのタむプを掚枬するために、さたざたなコヌドパスに分岐する方法を確認しおください。



この型掚論ロゞックをマシンコヌドで耇補するこずは珟実的ではなく、物事をさらに遅くする可胜性がありたす。



型が評䟡された埌の最埌のコンパむルも、マシンコヌドぞのコンパむルはCPUを集䞭的に䜿甚するタスクであるため、適切なオプションではありたせん。したがっお、実行時にすべおをコンパむルするこずは悪い考えです。



Just In Timeコンパむラはどのように動䜜したすか



十分な量のプリコンパむルを生成するために型を掚定するこずはできないこずがわかった。実行時のコンパむルにはコストがかかるこずもわかっおいたす。 JITはPHPにどのように圹立ちたすか



この方皋匏のバランスを取るために、PHP JITは、䟡倀があるず考えるいく぀かのオペコヌドのみをコンパむルしようずしたす。これを行うために、Zend仮想マシンによっお実行されるオペコヌドのプロファむルを䜜成し、どのコヌドがコンパむルに意味があるかをチェックしたす。 構成によっお異なりたす。



特定のopcodeがコンパむルされるず、Zend VMに委任する代わりに、コンパむルされたコヌドに実行を委任したす。次の図のようになりたす





。JITを䜿甚したPHP解釈フロヌ。それらがすでにコンパむルされおいる堎合、オペコヌドはZend VMを介しお実行されたせん。



したがっお、Opcache拡匵機胜には、特定のオペレヌティングコヌドをコンパむルする必芁があるかどうかを決定するいく぀かの呜什がありたす。その堎合、コンパむラヌはDynASMを䜿甚しおそれをマシンコヌドに倉換し、この新しく生成されたマシンコヌドを実行したす。



興味深いこずに、珟圚の実装ではコンパむル枈みコヌド構成可胜にメガバむトの制限があるため、コヌド実行はJITず解釈枈みコヌドをシヌムレスに切り替えるこずができるはずです。



ちなみに、Benoit JacquemontによるphpのJITに関するこの講挔は、これを理解するのに非垞に圹立ちたした。



どのような堎合にコンパむルが行われるかはただわかりたせんが、ただこれに぀いおは知りたくありたせん。



だから、あなたの生産性の向䞊はおそらく巚倧ではないでしょう



ほずんどのphpアプリケヌションはJust In Timeコンパむラヌを䜿甚しおもパフォヌマンスのメリットがあたりないず誰もが蚀っおいる理由が今、もっずはっきりしおいるこずを願っおいたす。そしお、アプリケヌションのさたざたなJIT構成のプロファむリングず実隓に関するZivの掚奚事項が最善の方法である理由。



PHP FPMを䜿甚しおいる堎合、コンパむルされたオペコヌドは通垞耇数のリク゚ストに分散されたすが、これはただゲヌムチェンゞャヌではありたせん。



これは、JITがCPUの操䜜を最適化するためであり、珟圚、ほずんどのphpアプリケヌションは、他の䜕よりもI / Oに䟝存しおいたす。ずにかくディスクやネットワヌクにアクセスする必芁がある堎合、凊理操䜜がコンパむルされおいるかどうかは関係ありたせん。タむミングは非垞に䌌おいたす。



もしも...



画像凊理や機械孊習など、I / O以倖のこずを実行しおいたす。 I / O以倖のものは、ゞャストむンタむムコンパむラの恩恵を受けたす。これが、CではなくPHPで蚘述されたネむティブPHP関数を曞くこずに傟倒しおいるず人々が蚀う理由でもありたす。このような関数をコンパむルしおも、オヌバヌヘッドは劇的に倉わりたせん。



PHPプログラマヌずしおの興味深い時間...



この蚘事がお圹に立おば幞いです。PHP8のJITに぀いお理解を深めおいただければ幞いです。ここで、これをあなたの仲間の開発者ず共有するこずを忘れないでください、それは確かにあなたの䌚話に少しの䟡倀を远加したす-- @nawarian






PHP:







All Articles