20
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

PHP8で追加されたJITと、PHP OPcacheについて徹底解説!「悪りぃが、こっから先は一方通行だ」

Last updated at Posted at 2021-06-11

はじめに

PHPerの皆さんこんにちは。一方通行と申します。
皆さんは去年(2020年)の11月にPHP 8がリリースされたのは既知のことかとは思いますが、
PHP 8の最も目玉である機能に「JIT (ジャストインタイム) コンパイル」というものがあります。

JITをPHPアプリケーションに導入しようか検討する際にJITが内部的に何を行っているのかきちんと理解していなければ導入出来ないと思い、
別の高速化アプローチであるOPcacheと合わせて、解説します。

雰囲気は知っているよという方や、OPcache is 何?という方々はぜひご参考にしてください。

前提知識

まずですが、インタプリタ言語がマシン上でどのように実行されているかおさらいしましょう。
大まかな流れは下図のとおりとなります。
qiita_php8_1.png

このようにソースコードを元に機械語まで変換するプログラムをインタプリタと呼びます。
PHP及びRubyやPythonのインタプリタはC言語で書かれています。

これらを踏まえた上で、説明していきます。

PHPの実行フローをおさらい

PHPの実行フローは下図のとおりです。
qiita_php8_3.png
ソースコードからOpcodeへ変換し、変換されたOpcodeをZend Engineが解釈し機械語へ変換していきます。

Opcode is 何?

ここで、新たにOpcodeという単語が出てきましたが、これは最初の図にあるバイトコードと同義です。
Opcodeとは仮想マシン(Zend VM)で実行できる疑似命令で、Opcodeは最終的に配列になり順次VMを介して実行されていきます。

以下のtest.phpをDebugした結果が、更に下のterminalのキャプチャで、
0000~0004までがOpcodeとなります。

test.php
<?php
$accelerator = '悪りぃが、';
echo $accelerator . 'こっから先は一方通行だ';

echo PHP_EOL;

スクリーンショット.png

Opcodeの処理内容を確認するにはここから確認できます。
(※ LinkはZend Engine 2のものです)

Zend Engine is 何?

Zend Engine(VM)はソースコードを中間表現(Opcode)に変換し、中間表現を実行します。

実行の度にソースコードを解析し機械語にコンパイルしていくより、
一旦ファイル単位でOpcodeへ変換しそれを実行する方がより高速でありリソース管理の面から優れているためZend VMが導入されました。

php -vを実行した際にZend Engineのバージョンとコピーライトが出てくるかと思いますがそれです。

OPcache is 何?

Opcodeを共有メモリに保存しておくことを指します。
つまり、OPcacheはPHPのアクセラレータと言えます。
図に表すと以下のとおりです。
qiita_php8_5.png

JIT is 何?

厳密な意味合いを言うと、VMの「バイトコード」を「ネイティブコード(機械語)」にコンパイルすることを指します。
そしてJITはコンパイルの際、ネイティブコード(機械語)のキャッシュを行います。

キャッシュが存在する場合はZend VMを挟む必要がなくなり、プロセッサレベルの命令として直接機械語の実行が可能となります。
qiita_php8_7.png

PHP JITの種類

Function JIT

Function JITは関数単位でJITコンパイルが行われます。
問題は関数単位で全てJITコンパイルするため、場合によってはパフォーマンスが低下する恐れがあるということです。

Tracing JIT

Tracing JITはランタイム情報を含んだスタックトレースを作成し、トレースの回数や内容を元にJITコンパイルするかを判別してくれます。(ホットコードを識別して最適化)
qiita_php8_8.png

カスタマイズ

4桁の整数値 CRTO を入力することで、JITのトリガーや最適化レベルを変更できます。
詳しくはこちらを参照ください。

あとがき

PHP 8で導入されたJITは、簡素に説明してしまえば「OPcacheより高速化が見込めるキャッシュ機能」と言えるわけですが、
実際はOPcacheとは切り離して考えることは出来ず、インタプリタの実行フローを把握していないと全貌を捉えることが出来ませんでした。

また、記事執筆にあたり新たな発見があり自分的にも書いてよかったと思っています。

PHPは言語仕様がちょっとアレなところはありますが、なんでも取り込む貪欲な姿勢からは今後も目が話せませんね。

ここまで読んで頂きありがとうございました!

採用PR

20
11
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
20
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?