Upgrade to Pro — share decks privately, control downloads, hide ads and more …

ソースコードから理解するPreloadとJITの話/preload_and_jit

 ソースコードから理解するPreloadとJITの話/preload_and_jit

preloadとJITの話をなるべくわかり易く、それでいて深く書いてみました。

Ryo Tomidokoro

December 12, 2020
Tweet

More Decks by Ryo Tomidokoro

Other Decks in Programming

Transcript

  1. @hanhan1978
    ソースコードから理解する
    PreloadとJITの話
    PHP Conference Japan 2020/12/12

    View Slide

  2. @hanhan1978
    ● 富所 亮
    ● 職業
    ○ Webアプリケーションエンジニア
    ○ 雑用係
    ● ブログ
    ○ https://blog.hanhans.net
    ● Yokohama North AM
    ○ https://anchor.fm/yokohama-north-am

    View Slide

  3. 興味のある方は...
    ※気が向いた時にやってます ...
    https://shadow-php.connpass.com/

    View Slide

  4. 秒でGDBデバッグ
    https://github.com/hanhan1978/shadow-php/wiki

    View Slide

  5. 本日のテーマ
    preloadとjitの肌感を掴む
    ● 謎の技術にせず、仕組みから理解
    ● どれくらい速度向上するのか
    ● 本番環境での採用是非

    View Slide

  6. PHP高速化の歴史

    View Slide

  7. PHPはスクリプト言語
    実行の大まかな流れ

    View Slide

  8. PHPはスクリプト言語
    実行の大まかな流れ
    ここで時間がかかる

    View Slide

  9. PHPerが行ってきた解決策

    View Slide

  10. 中間コードキャッシュ
    コンパイル結果(OPCode)をメモリにキャッシュ

    View Slide

  11. 歴代の中間コードキャッシュ
    XCache 〜PHP5.6
    eAccelarator 〜PHP5.6
    Alternative PHP Cache (APC) PHP5.4
    Zend Opcache PHP5.5〜
    ※これらのツールを同居させると ShareMemory戦国時代になりSegFault

    View Slide

  12. OPCacheがデファクトスタンダード
    PHP5.5以降は一択
    そして、PHP7.4以降からOPCacheにさらなる高速化の仕組みが
    導入されるようになった....ここから本題

    View Slide

  13. 余談1
    稀によく見るうっかりさん。OPCache入ってない
    ※php -v ですぐ確認できるので、心当たりのある方は確認を

    View Slide

  14. ※OPcacheが入ってなくて良いことは一個もないです

    View Slide

  15. PHPスクリプト実行の詳細

    View Slide

  16. PHPはスクリプト言語
    ● 実行時にコンパイル
    ● コンパイル&実行を繰返す

    View Slide

  17. 例えば

    View Slide

  18. PHP実行の流れ

    View Slide

  19. View Slide

  20. 実行の詳細

    View Slide

  21. View Slide

  22. View Slide

  23. 中間コードキャッシュに
    よってコンパイルの過程
    が省略される

    View Slide

  24. 具体例

    View Slide

  25. ファイル構成

    View Slide

  26. index.php

    View Slide

  27. autoload.php

    View Slide

  28. A.php

    View Slide

  29. B.php

    View Slide

  30. 実行すると

    View Slide

  31. 実行すると
    autoloaderが2回呼び出されている

    View Slide

  32. 実行の流れ

    View Slide

  33. 4回のコンパイル

    View Slide

  34. OPCacheが解決するもの
    4回分のコンパイルがキャッシュで解決

    View Slide

  35. 計測

    View Slide

  36. OPCache − ◯
    Req / Sec 111.55 680.42
    ※OPCacheの有効化によって、処理速度は約 6倍
    Laravelの30秒ベンチマーク

    View Slide

  37. 高速化技術が達成すること
    1. OPCache >>
    2. OPCache preload >>
    3. OPCache JIT >>
    ???
    ???
    ???

    View Slide

  38. 高速化技術が達成すること
    1. OPCache >> コンパイル回数の軽減
    2. OPCache preload >>
    3. OPCache JIT >>
    ???
    ???

    View Slide

  39. OPCache preloadとは?

    View Slide

  40. PHP7.4から追加
    https://wiki.php.net/rfc/preload

    View Slide

  41. ● OPCacheの機能追加として提案
    ● サーバー起動時に指定ファイルをコンパイル
    して、メモリに読込
    ※一見すると、中間コードキャッシュと同じことをしているように見える

    View Slide

  42. 具体例

    View Slide

  43. ファイル構成

    View Slide

  44. preload.php

    View Slide

  45. php.ini

    View Slide

  46. 実行すると

    View Slide

  47. 実行すると
    Class Aはautoloadされてない!!

    View Slide

  48. 実行の流れ

    View Slide

  49. 3回のコンパイル

    View Slide

  50. ● autoloadが省略される
    ● preload以外のファイルは
    opcache.validate_timestamp=0と同じ挙動
    ● 直接のrequireはpreloadが活用されない

    View Slide

  51. preloadソース v7.4.3

    View Slide

  52. ext/opcache/ZendAccelarator.c
    - SAPI起動時に L4200 preload_load()
    - globalなデータ領域にpreloadしたクラス、ファイルの情報を登録
    する
    - opcodes実行時のコンパイルに使われるのは、L1914
    persistent_compile_file。これはpreloadの有無に依らない

    View Slide

  53. Zend/zend_execute_API.c
    - L1419 zend_fetch_class_by_name が未解決のクラス名に対して
    コールされる
    - zend_hash_findでコンパイル済みのクラスが発見されれば、それを
    使う(preload)
    - それ以外は、autoloaderを使ってクラスの解決が行われて、ファイル
    が見つかればコンパイルされる
    ※要するにpreloadされるとautoloaderまで処理がいかずに解決できる

    View Slide

  54. 計測

    View Slide

  55. Laravelの30秒ベンチマーク
    OPCache − ◯ ◯
    Preload − − ◯
    Req / Sec 111.55 680.42 774.14
    ※preload有効化によって、処理速度は約 14%向上

    View Slide

  56. 高速化技術が達成すること
    1. OPCache >> コンパイル回数の軽減
    2. OPCache preload >>
    3. OPCache JIT >>
    ???
    ???

    View Slide

  57. 高速化技術が達成すること
    1. OPCache >> コンパイル回数の軽減
    2. OPCache preload >> autoloadの軽減
    3. OPCache JIT >> ???

    View Slide

  58. 余談
    Windows用PHPのpreload機能は7.4.2の時点で機能削除
    https://www.php.net/manual/en/opcache.preloading.php

    View Slide

  59. OPCache JITとは?

    View Slide

  60. PHP8.0から追加
    https://wiki.php.net/rfc/jit

    View Slide

  61. ZendVMで実行するのではなく
    Native Codeを実行する

    View Slide

  62. ● 機械語実行により処理速度が最適化
    ● 同様のことはpcre-jitやJS等でもおなじみ

    View Slide

  63. 実行の詳細

    View Slide

  64. View Slide

  65. View Slide

  66. OPCodeをさらに機械語に変換
    CPUで直接実行!!

    View Slide

  67. ● コード実行が最適化
    ● JITコンパイルのオーバーヘッドは実行速度で
    補填

    View Slide

  68. JITソース v8.0.0

    View Slide

  69. OPCacheが主に関わってくるソースコード
    JIT関連はopcache/jitに固まっているので
    分かりやすい。

    View Slide

  70. opcodeをx86のアセンブラに変換している
    zend_jit_x86.c

    View Slide

  71. ext/opcache/jit/zend_jit.c
    - zend_jit_op_array において泥臭い変換処理が行われている
    - アーキテクチャ依存のコード変換なので未対応だと動作しない
    - LuaJIT由来のDynAsmを利用

    View Slide

  72. JIT化される単位
    - zend_jit_op_array はファイル毎に呼び出し
    - クラス単位、関数単位でopcodeの最適化が行われて、関数のIOを合わ
    せた形でZendVMの主処理と繋ぎ合わされる
    - 1ファイル1関数に全部の処理を入れたら、効果的に効きそう

    View Slide

  73. 計測

    View Slide

  74. Laravelの30秒ベンチマーク
    OPCache − ◯ ◯
    Preload − − ◯
    Req / Sec 111.55 680.42 774.14
    Req / Sec (JIT) − 696.57 812.93
    ※JIT有効化によって、処理速度は約 2.5〜5%向上

    View Slide

  75. モンテカルロ法を計測

    View Slide

  76. 円周率計算のベンチマーク
    OPCache − ◯
    Sec 9.74 8.96
    Sec (JIT) − 5.20
    ※JIT有効化によって、処理速度は約 42%向上
    100,000,000回試行の処理時間

    View Slide

  77. 高速化技術が達成すること
    1. OPCache >> コンパイル回数の軽減
    2. OPCache preload >> autoloadの軽減
    3. OPCache JIT >> ???

    View Slide

  78. 高速化技術が達成すること
    1. OPCache >> コンパイル回数の軽減
    2. OPCache preload >> autoloadの軽減
    3. OPCache JIT >> コード実行の最適化

    View Slide

  79. JITの現状

    View Slide

  80. ● https://bugs.php.net/search.php?cmd=display&packa
    ge_name[]=opcache
    ● RedditのPHP系板
    ● https://www2.slideshare.net/nikita_ppv/justintime-co
    mpiler-in-php-8
    情報キャッチアップ

    View Slide

  81. 使用上の注意

    View Slide

  82. ● 内部の実行パスが変わる
    ● 開発も同じ設定にするのが吉
    ● ファイル更新でopcache_clearとか...

    View Slide

  83. phpunitで使うには
    これを設定しないと、コマンドライン実行時にopcache
    が動かない。

    View Slide

  84. まとめ

    View Slide

  85. 高速化技術が解決すること
    1. OPCache >> コンパイル回数の軽減
    2. OPCache preload >> autoloadの軽減
    3. OPCache JIT >> コード実行の最適化

    View Slide

  86. 仕組みを理解
    適切なアプリケーションに適用
    コレ大事!!

    View Slide

  87. 参考1
    https://speakerdeck.com/hanhan1978/web-application-tuning-guildline

    View Slide

  88. 参考2
    https://gist.github.com/hellerbarde/2843375
    Network IOはメモリアク
    セスの5万倍遅い

    View Slide

  89. リアルなウェブアプリのボトルネックは、大半
    がDBアクセス
    CPU負荷の数%は全体のボトルネックでは
    微々たるもの

    View Slide

  90. 本番投入はオススメしづらい...
    ISUCON用機能なのでは...

    View Slide