Contenu connexe Similaire à PHP 8 で Web 以外の世界の扉を叩く (20) PHP 8 で Web 以外の世界の扉を叩く1. PHP 8 でWEB 以外の世界の扉
を叩く
五⼗嵐進⼠/ sji / sj-i / @sji_ch
17. ⾮同期通信+ Preloading + でマルチスレッド
解析スレッド
対象プロセス上での処理系の内部データのメモリアドレス
を特定
PHP で処理系のバイナリデータをパース
Linux のプロセス情報ファイルをパース
FFI でシステムコールを呼んで対象プロセスのメモリを覗
き⾒
処理系の内部データ構造を解釈してコールトレースを抜き
出す
集計出⼒スレッド
FFI でGUI のウィンドウを描画
コールトレースの集計をとる
JIT
18. ⾮同期通信+ Preloading + でマルチスレッド
解析スレッド
対象プロセス上での処理系の内部データのメモリアドレス
を特定
PHP で処理系のバイナリデータをパース
Linux のプロセス情報ファイルをパース
FFI でシステムコールを呼んで対象プロセスのメモリを覗
き⾒
処理系の内部データ構造を解釈してコールトレースを抜き
出す
集計出⼒スレッド
FFI でGUI のウィンドウを描画
コールトレースの集計をとる
JIT
25. RFC 作成⽇
Shorter Attribute Syntax Change 2020-
08-04
Don't automatically unserialize Phar metadata
outside getMetadata()
2020-
07-07
Reclassifying engine warnings 2019-
08-27
Ensure correct signatures of magic methods 2020-
04-05
26. RFC 作成⽇
Named Arguments 2020-05-05
Treat namespaced names as single token 2020-06-15
Saner string to number comparisons 2019-02-26
Saner numeric strings 2020-06-28
27. RFC 作成⽇
Remove inappropriate inheritance signature checks
on private methods
2020-
04-16
Match expression v2 2020-
05-22
Attribute Amendments 2020-
05-11
Make sorting stable 2020-
05-12
28. RFC 作成⽇
Locale-independent oat to string cast 2020-03-
11
Change Default PDO Error Mode 2020-03-
28
Stricter type checks for arithmetic/bitwise
operators
2020-04-
02
Add str_starts_with() and str_ends_with() functions 2020-03-
25
29. RFC 作成⽇
Validation for abstract trait methods 2020-02-
07
Add Stringable interface 2020-01-
15
Implement new DOM Living Standard APIs in
ext/dom
2019-09-
15
Arrays starting with a negative index 2017-04-
20
31. PHP 8.0 ⽤のブランチは2019 年1 ⽉
に出てる
php-master-changes 2019-01-28
https://qiita.com/sj-i/items/418282051c3c647e7aed#nikic-
clear-news-upgrading-and-upgradinginternals
42. PHP 8 は内部的なエンジン変更は⼩さい
Dmitry ⼤先⽣も⼤したことないって⾔ってる
https://externals.io/message/112291#112295
PHP 8.0 didn't introduce revolutionary
engine changes (like PHP 7 and PHP 5 did)
46. "PHP 8 NEXT?"
2018 年6 ⽉に、コア開発者のnikita さんがinternals に投稿
「次のバージョンPHP 8 になりそうな雰囲気を感じてるんだけ
ど、実際どうなの?」というメール
https://externals.io/message/102378
52. PHP 2^3
Zeev さんが話の流れに乗ってML へ投下した8 への意気込みメ
ール
https://externals.io/message/102415
次のメジャーバージョンではJIT やFFI、⾮同期処理や⻑時間実
⾏スクリプトのサポートやpreloading の機能を盛り込みたい
53. PHP 2^3
Zeev さんが話の流れに乗ってML へ投下した8 への意気込みメ
ール
https://externals.io/message/102415
次のメジャーバージョンではJIT やFFI、⾮同期処理や⻑時間実
⾏スクリプトのサポートやpreloading の機能を盛り込みたい
7.3 のリリース後はPHP 8 に向けて開発⼒を集中したい
54. PHP 2^3
Zeev さんが話の流れに乗ってML へ投下した8 への意気込みメ
ール
https://externals.io/message/102415
次のメジャーバージョンではJIT やFFI、⾮同期処理や⻑時間実
⾏スクリプトのサポートやpreloading の機能を盛り込みたい
7.3 のリリース後はPHP 8 に向けて開発⼒を集中したい
7.4 は8 の準備で廃⽌予定機能⾮推奨化オンリーのスリムなリリ
ースに
58. 「次はPHP 8」は残った
2018 年11 ⽉、Nikita さんから"Branch off PHP-7.4 early" とい
うメールがintenals へ
早めに7.4 のブランチ切ってmaster へ8 向けの作業を⼊れて
いけるようにする提案
59. 「次はPHP 8」は残った
2018 年11 ⽉、Nikita さんから"Branch off PHP-7.4 early" とい
うメールがintenals へ
早めに7.4 のブランチ切ってmaster へ8 向けの作業を⼊れて
いけるようにする提案
2019 年1 ⽉28 に実際にPHP 7.4 のブランチが切られる
60. 「次はPHP 8」は残った
2018 年11 ⽉、Nikita さんから"Branch off PHP-7.4 early" とい
うメールがintenals へ
早めに7.4 のブランチ切ってmaster へ8 向けの作業を⼊れて
いけるようにする提案
2019 年1 ⽉28 に実際にPHP 7.4 のブランチが切られる
同⽇にJIT のRFC ページが作られる
61. 「次はPHP 8」は残った
2018 年11 ⽉、Nikita さんから"Branch off PHP-7.4 early" とい
うメールがintenals へ
早めに7.4 のブランチ切ってmaster へ8 向けの作業を⼊れて
いけるようにする提案
2019 年1 ⽉28 に実際にPHP 7.4 のブランチが切られる
同⽇にJIT のRFC ページが作られる
この段階でFFI とPreloading はPHP 7.4 向けで受理済
66. PHP 8 のためのJIT のためのPHP
7.4 の機能
JIT 実装はLuaJIT を参考にしたもの
FFI もJIT との組み合わせを念頭に置きつつLuaJIT にもとづいて
提案
Preloading もJIT / FFI との組み合わせも念頭に置きつつ提案
まだ完全な姿ではないがコマは揃ってきた
67. PHP 8 のビジョン
Zend / Dmitry さんの7 年以上に渡る取り組みの成果がJIT とそ
の周辺機能
既存のアプリケーションでさほどの性能向上が⾒られないと分か
っていたにも関わらず断⾏された
何か強い明確なビジョンがある
68. PHP 8 のビジョン
Zend / Dmitry さんの7 年以上に渡る取り組みの成果がJIT とそ
の周辺機能
既存のアプリケーションでさほどの性能向上が⾒られないと分か
っていたにも関わらず断⾏された
何か強い明確なビジョンがある
つまり既存のPHP アプリケーションの枠内にはないことをやれ
るようになること!
73. TRACING JIT と関数JIT
JIT にはtracing JIT とfunction JIT のモードがある
opcache.jit で切り替え
デフォルトはtracing JIT
こっちの⽅がたいてい速い、中⾝は少し複雑
2019 年1 ⽉のRFC 当時はまだなかった
2020 年3 ⽉頃に⼊った
82. FFI 導⼊以前
7.3 までのPHP はできないことが多かった
標準関数の範囲外はC の拡張機能が必要
実際は標準関数⾃体も処理系に標準添付された拡張という形
拡張を作るには処理系の特殊な作法と⼀定以上のC ⾔語知識が
必要
83. FFI 導⼊以降
C ⾔語資産をPHP から直接呼べる
システムコールやメモリ操作の関数、処理系の内部関数など
など
当然リスクも⼀緒に持ち込まれる
PHP 処理系内部の深い知識、拡張を書く際の特有の作法は不要
C ⾔語の知識は必要
84. FFI の使い⽅$ffi = FFI::cdef(
'int printf(const char * restrict format, ... );',
// 'libc.so' /* libc は処理系とともに読み込まれているので不要 */
);
$ffi->printf('hello clang world');
89. FFI から演算⼦オーバーロードしてみる
Z-Engine を利⽤
class A {}
$refClass = new ReflectionClassEx(A::class);
$handler = Closure::fromCallable([ObjectCreateTrait::class, '__init']);
$refClass->setCreateObjectHandler($handler);
$refClass->setCompareValuesHandler(fn (...$args) => 0);
var_dump(new A() == 1); // true になる
var_dump(new A() == 'string'); // true になる
95. GTK でPHP からウィンドウを作る
include __DIR__ . '/../vendor/autoload.php';
const PHP_GTK_DEV_DEBUG = false;
$gtk = PHPGtk::gtk();
$gtk->gtk_init($argc, $argv);
$mainwin = $gtk->gtk_window_new(GtkGtkEnum::GTK_WINDOW_TOPLEVEL);
$gtk->gtk_widget_show_all($mainwin);
$gtk->gtk_main();
96. GTK でPHP からボタン押下時のコールバックを使う
こんなコード追加だけでいける
$button = $gtk->gtk_button_new_with_label('button');
$callback = function () {
echo 'hello';
};
$gtk->g_signal_connect($button, 'clicked', $gtk->G_CALLBACK($callback), null);
$gtk->gtk_container_add($gtk->GTK_CONTAINER($window), $button);
102. THE FREE LUNCH WAS OVER
今どきのCPU はマルチコア、4 以上のコアも当たり前になって
きた
JIT でシングルスレッド性能を上げるだけでは⾜りない
106. ZTS によるスレッド拡張
ZTS はWeb サーバでのリクエスト処理の⼟台で使う仕組み
PHP スクリプトからスレッドを作るためのAPI は提供されてい
ない
拡張でZTS にもとづきスレッド機能を提供するものが存在
有名なのはpthreads
107. EXT-PTHREADS
PHP Threads の略
POSIX スレッドの単なるラッパーではない
どちらかというとJava っぽい雰囲気のAPI
作者はkrakjoe (Joe Watkins) さん
phpdbg やpcov やapcu の作者でもある
2019 年に開発中⽌、PHP 7.4 以降への対応はしない→parallel
へ
https://github.com/krakjoe/pthreads
109. PARALLEL の使い⽅
<?php
$runtime = new parallelRuntime();
$future = $runtime->run(function(){
for ($i = 0; $i < 500; $i++)
echo "*";
return "easy";
});
for ($i = 0; $i < 500; $i++) {
echo ".";
}
printf("nUsing parallelRuntime is %sn", $future->value());
112. CHANNEL
$channel = new parallelChannel();
$runtime = new parallelRuntime();
$future = $runtime->run(
function(parallelChannel $channel){
$message = $channel->recv();
echo $message;
},
[$channel]
);
$channel->send('message');
114. ZEND のND の⼈だって⾔っている
Zend のnd の⽅の⼈も昔同じようなことを⾔っていた
もしスレッドを実装するとしたら、⼀番良いの
はそれぞれが⾃前のコンテキストを持ったワー
カースレッドを⽣成できるようにして、データ
共有はしない(だからロックも要らない)奴だ
ろうね。そしてスレッド間でメッセージパッシ
ングするAPI を提供する。-- Andy Gutmans
( )https://externals.io/message/47701#47729
117. なぜPARALLEL が⽣まれたのか: 訳
pthreads と別の並列処理API を作りたい、みたいなのはしばら
くなかった
Zend の⼈たちが年⽉を費やして作ってきたJIT のマージに向け
て動くまではね
ちょっと考えてみてほしい
これはつまりユーザランドのPHP によって機械語のコードを並
列実⾏できるってことだよね?
121. JIT + PARALLEL のデモ
再度ファミコンエミュレータを改修
描画スレッドとCPU / PPU で描画する内容を計算するスレッド
を分ける
前のフレームを描画しきる前に描画内容の計算が終わった場合、
そのフレームの描画をスキップ
122. JIT + PARALLEL のデモ
再度ファミコンエミュレータを改修
描画スレッドとCPU / PPU で描画する内容を計算するスレッド
を分ける
前のフレームを描画しきる前に描画内容の計算が終わった場合、
そのフレームの描画をスキップ
JIT だと計算スレッドが300 FPS くらい出る
126. AMPHP + PSALM ⼩話
実はpsalm にamphp をサポートする機能@psalm-yieldというも
のがあり、Promise に付いてる
Promise<T>をyield するとTが返ってくるものとして型解析
本当はamphp のループ外で使ったら別の値が来るかもしれな
い、のだが、そこは無視
128. JIT は発展途上
速くはなってもJIT エンジン界ではまだまだ新参者
The Computer Language Benchmarks の多くのベンチマークでま
だNode には結構負けてる
PHP 8 の今後に期待
tracing JIT 導⼊(約1 年)での性能向上実績もある
https://benchmarksgame-
team.pages.debian.net/benchmarksgame/fastest/php.html
130. FFI もまだ発展途上
LuaJIT で⼊ってるようなC を越えるレベルの最適化はまだない
When FFI Function Calls Beat Native C
でもそのうち⼊る筈、PHP でもC に勝てる⽇が来るか?
https://nullprogram.com/blog/2018/05/27/
133. PHP とPHPER の進化
PHP 4 にはまともなオブジェクト指向機能さえなかった
今は成熟したオブジェクト指向機能もあれば静的型検査のエコシ
ステムもある
PHP プログラマもこれらの機能に習熟してきた
Web なら「それPHP でもできるし、PHP で別にいいじゃない」
と⾔える
134. PHP とPHPER の新たな挑戦
PHP でFFI もマルチスレッドも⾮同期処理もある程度できるよ
うになってきた
JIT まで⼊った
⾔語とエコシステムとしては準備が整ってきている
しかしPHP プログラマの⽅はどうか
「Web 以外だってPHP でも別にいいじゃない」と⾔えるのか