Upload
yoshio-hanawa
View
14.714
Download
6
Embed Size (px)
Citation preview
Zend OPcacheの速さの秘密を探る
hnwPHPカンファレンス2013(2013/09/14) 発表資料
13年9月14日土曜日
自己紹介
@hnw / id:hnw
勤務先:KLab株式会社
社内PHP案件の助っ人など(性能改善とか)やってます
カレーとバグが大好物
おいしい情報をお待ちしています
13年9月14日土曜日
今日おはなしすること
Zend OPcache とは
最適化フェーズの内側
安定性をどう判断するか
13年9月14日土曜日
Zend OPcache とは
最適化フェーズの内側
安定性をどう判断するか
13年9月14日土曜日
Zend OPcache とは
PHPのopcodeキャッシュ&最適化エクステンション
PHP 5.5に標準添付、APCの代替として期待されている
PHP 5.2から5.5に対応
前身: Zend社の商用製品(Zend Optimizer)
2013年2月 Open Source化、名前も変わった
13年9月14日土曜日
APC との違い
KVS 機能が無い
APCu などを併用しましょう
バイトコードの最適化を行う
これが速さの秘密
13年9月14日土曜日
Zend OPcache の性能
ベンチマークテスト
Opcode Cache Benchmarks
全般的にAPCより速い
仕組み上も有利
APCより遅くなる状況が珍しい
13年9月14日土曜日
OPcacheが行う「最適化」って何?
13年9月14日土曜日
素のPHPの処理PHPコードをopcodeに変換してからVM実行している
Parser
Lexer
Opcode Compiler
Zend VM
PHP
token
AST
opcode
13年9月14日土曜日
素のPHPの処理PHPコードをopcodeに変換してからVM実行している
Parser
Lexer
Opcode Compiler
Zend VM
PHP
token
AST
opcode
13年9月14日土曜日
opcodeの例
参考:Opcode Descriptions and Examples
<?phpif (false) { echo ”*”;}
13年9月14日土曜日
素のPHPの処理PHPコードをopcodeに変換してからVM実行している
Parser
Lexer
Opcode Compiler
Zend VM
PHP
token
AST
opcode
13年9月14日土曜日
Zend VM概要
最大4オペランドのレジスタマシン
レジスタ数は無限個
各レジスタの変数型は実行時まで決定できない
命令数 146(PHP 5.5.3時点)
13年9月14日土曜日
PHP+APCの処理opcodeキャッシュにより、PHPの解釈をスキップできる
Parser
Lexer
Opcode Compiler
Zend VM
PHP
token
AST
opcode
Opcode Cacheopcode
13年9月14日土曜日
PHP+OPcacheの処理opcodeレベルの最適化処理を行い、キャッシュする
Parser
Lexer
Opcode Compiler
Zend VM
Optimizer
PHP
token
AST
opcode
opcode
Opcode Cacheopcode
13年9月14日土曜日
最適化の例opcode数を減らしたり、効率の良いものに置換したりする
OPcache無効:4opcodes
OPcache有効:1opcode13年9月14日土曜日
VLDopcodeを確認するためのPHP extension
http://derickrethans.nl/projects.html#vld
メンテナ:Derick Rethans
GitHub上ではPHP 5.5に対応済み
https://github.com/derickr/vld
5.5対応のパッチは僕が書きました。バグレポよろしく。
13年9月14日土曜日
Zend OPcache とは
最適化フェーズの内側
安定性をどう判断するか
13年9月14日土曜日
OPcacheの最適化内容substitute persistent constants (true, false, null, etc)perform compile-time evaluation of constant binary and unary operations
optimize series of ADD_STRING and/or ADD_CHAR
convert CAST(IS_BOOL,x) into BOOL(x)convert INTI_FCALL_BY_NAME + DO_FCALL_BY_NAME into DO_FCALL
convert non-numeric constants to numeric constants in numeric operatorsoptimize constant conditional JMPs
optimize static BRKs and CONTs
optimize $i = $i+expr to $i+=exproptimize series of JMPs
change $i++ to ++$i where possibleCFG optimization
Optimize temp variables usage
remove NOPs
高度な最適化は行っていない印象
13年9月14日土曜日
最適化の具体例(1)コンパイル時に評価できる場所は先に評価する
「$seconds_in_a_day = 60*60*24;」
あらかじめ 86400 として変数にセットする
13年9月14日土曜日
最適化の具体例(1)OPcacheなし
60を60倍して、さらに24倍している
13年9月14日土曜日
最適化の具体例(1)OPcacheあり
60*60*24した結果をいきなり変数に代入
13年9月14日土曜日
最適化の具体例(2)可能であれば $i++ を ++$i に変える
式 $i++ の結果を利用していない場合、両者は交換可能
交換するとopcode数が減る
$i++ はZend VM上では2命令に展開される
++$i は1命令に展開される
13年9月14日土曜日
最適化の具体例(3)無駄なジャンプ命令を削除する
ジャンプ命令の飛び先がジャンプ命令になる場合がある
2重ループの終端など
<?phpfor ($i = 0; $i < 10; $i++) { for ($j = 0; $j < 10; $j++) { $sum += $arr[$i][$j] }}
13年9月14日土曜日
OPcacheがやらないこと(1)
共通部分式の除去 (Common Subexpression Elimination)
下記コードには「$_GET[’x’]」が2回出現
opcodeレベルでは3命令、一時変数に格納すれば有利
<?php$y = $_GET[’x’] + 1;$z = $_GET[’x’] - 9;
13年9月14日土曜日
OPcacheがやらないこと(2)
ループ不変式の追い出し (Loop Invariant Motion)
可能であればループ内の式をループ外に追い出す
例:下記の「$a=$b*$c」をループ外に追い出す
<?phpfor ($i = 0; $i < 10; $i++) { $a = $b * $c; ...($a,$b,$cの値がループ内で不変)
}
13年9月14日土曜日
最適化の効果ひとつひとつの最適化の効果はごく僅か
この手の最適化は「ちりも積もれば」的な部分が大きい
人力で行っても報われないことが多い
細かい最適化が好きな人はOPcacheに機能追加しよう!
教科書的な内容で未実装のものが多い
13年9月14日土曜日
Zend OPcache とは
最適化フェーズの内側
安定性をどう判断するか
13年9月14日土曜日
APCとの比較
PHP 5.4用のAPCはずっとbeta
高負荷サイトでのホットデプロイ時に白画面になる事故
OPcache はPHP 5.5から本体添付、5.5なら鉄板
PHP 5.2以降をサポートしている
PHP 5.4との組み合わせも要注目
13年9月14日土曜日
OPcacheの枯れ具合
一定の安心感
開発開始から約10年、Zend社の製品として提供
PHPのコアコミッターが複数人参加している
今までソースコードが出ていなかった分、ポカがありうる
最近バグ報告しました / PHP5.5.2 に入ってます
zendtech/ZendOptimizerPlus PR#113
13年9月14日土曜日
まとめOPcacheの最適化
仕組みとしても、実測値から見ても有効
まだ最適化の余地がある
OPcacheの安定性
APCより良いのでは(特に5.4+)
一定レベル以上ではないか
13年9月14日土曜日
ご静聴ありがとうございました
13年9月14日土曜日