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

作ってわかる!非同期ランタイム

Tech Leverages
March 04, 2025
88

 作ってわかる!非同期ランタイム

Tech Leverages

March 04, 2025
Tweet

Transcript

  1. CPU Intel Core i9 • 動作周波数:2.3 ~ 6.0GHz → 1秒間に23億回

    ~ 60億回の計算が 可能 https://i.gzn.jp/img/2017/07/07/intel-core-i9-7900x/00.jpg,(参照2025-02-05)
  2. CPU Intel Core i9 • 動作周波数:2.3 ~ 6.0GHz → 1秒間に23億回

    ~ 60億回の計算が 可能 → CPUが一回の計算にかかる時間は 0.2 ~ 0.5ナノ秒 https://i.gzn.jp/img/2017/07/07/intel-core-i9-7900x/00.jpg,(参照2025-02-05)
  3. CPUとコンポーネント間の通信にかかる時間 レジスタ :0.2 ~ 0.5 ナノ秒 RAM :80 ~ ナノ秒

    SSD (SATA3.0) :100 ~ マイクロ秒 HDD (SATA3.0) :10 ~ ミリ秒 ネットワーク :10 ~ 100 ミリ秒 図:Socket AM3+マザーボードの進化系、GIGABYTE「GA~990FXA-UD5 R5」徹底検証 https://www.gdm.or.jp/review/2015/0515/114349/2,(参照2025-02-05)
  4. CPUとコンポーネント間の通信にかかるクロック数 レジスタ :1 クロック RAM :400~ クロック SSD (SATA3.0) :50,000~

    クロック HDD (SATA3.0) :5,000,000~ クロック ネットワーク :5,000,000~ クロック 図:Socket AM3+マザーボードの進化系、GIGABYTE「GA~990FXA-UD5 R5」徹底検証 https://www.gdm.or.jp/review/2015/0515/114349/2,(参照2025-02-05)
  5. CPUとコンポーネント間の通信にかかるクロック数 CPUがHDDにアクセスしてデータを得るまでに一 千万回計算ができる! レジスタ :1 クロック RAM :400~ クロック SSD

    (SATA3.0) :50,000~ クロック HDD (SATA3.0) :5,000,000~ クロック ネットワーク :5,000,000~ クロック 図:Socket AM3+マザーボードの進化系、GIGABYTE「GA~990FXA-UD5 R5」徹底検証 https://www.gdm.or.jp/review/2015/0515/114349/2,(参照2025-02-05)
  6. CPU bound • CPUの処理速度によって律速され る • プロセスレベルで最適化するために は並列処理が有効 • 特定のワークロードに最適化された

    専用ハードウェアを使うことで最適 化が可能(ネットワーク、グラフィッ ク、暗号化) I/O bound • ディスクのIOPS、レイテンシによっ て律速される • プロセスレベルで最適化するために は並行処理が有効 • HDD→SSDにするなどしてスルー プットやレイテンシを向上させること で最適化が可能
  7. CPU bound • 文字列処理(正規表現など) • 全文検索 • 暗号化 • ハッシュ化

    • 圧縮・解凍処理 • 画像処理 • 動画エンコード I/O bound • ファイルの読み取り・書き出し • APIへのリクエスト • メモリスワップ 基本的なWebアプリケーションはほとんど I/Oが問 題になる(テーブルフルスキャン , N + 1問題, 外部 API連携, …etc)
  8. 言語機能として組み込み • JavaScript(Promise) • Java(CompletableFuture) • Kotlin(Coroutines) • Scala(Future) •

    Go(Goルーチン) • C#(Task) • Erlang ライブラリとして提供 • Rust(tokio) • C言語 • PHP(ReactPHP) • Python(asyncio)
  9. 非同期処理ランタイムを構成しているもの • Executor • Scheduler • (Reactor) • Task TaskをSchedulerから受け

    取って実際に処理を行う 実装によっては他の ExecutorからTaskを奪うこと もある(stealing)
  10. 非同期処理ランタイムの構成例 Executor Executor Executor Scheduler 実行キュー Task Task Task Task

    Task ランタイム I/Oキュー Task Reactor Executorは処理をある程度 進めると実行キューに戻す
  11. 非同期処理ランタイムの構成例 Executor Executor Executor Scheduler 実行キュー Task Task Task Task

    Task ランタイム I/Oキュー Task Reactor Executorは処理をある程度 進めると実行キューに戻す 処理は実行・中断・再開が 可能でないといけない
  12. タスクA,B,Cを A 1 →B 1 →C 1 →A 2 →…と進

    めることで非同期処理が 可能になる
  13. 今回作るもの • Executor • Scheduler • (Reactor) • Task シングルスレッドで実行する

    のでExecutorは必要ない 非同期I/Oはサポートしない 非同期処理の状態を管理す るTaskとTaskを実行する Schedulerのみを実装する
  14. さらなる高みへ ー 最適化への道 • V8エンジンの制約によりNode.jsでは不可能だったが、複数Executorによる並列処 理を実装することで更にスループットが向上する ◦ Rust(tokio)はイベント駆動 × マルチ軽量スレッド

    ◦ Goは同期IO × マルチ軽量スレッド ◦ Node.jsはイベント駆動 × シングルスレッド • 今回は非同期I/Oを実装しなかったが、I/Oをポーリングするのではなくイベント駆動 にすることで計算負荷が低減する