# アプリケーション並行実行モデル ## 定義 並行実行(concurrency)は複数の実行可能プログラムをロードし実行を開始できる機能であり、実行時間は重なり合うが必ずしも同時にon-CPUで実行されるわけではない。並列処理(parallelism)は、複数CPUを同時に使って1つのアプリケーションを実行することであり、それぞれ独自のタスクを実行する複数プロセス(マルチプロセス)または複数スレッド(マルチスレッド)を使うアプリケーションでなければ実現できない。マルチスレッド(または同等のタスク)の方が一般に効率的で望ましいアプローチとされる。(Source: [[@2023__OReillyJapan__詳解 システム・パフォーマンス 第2版 - Chapter 5 アプリケーション]] §5.2.5) OSスレッドによるマルチプロセス・マルチスレッドはカーネルのスケジューラを介するためコンテキストスイッチのオーバーヘッドがかかる。これを避けるため、ユーザーモードアプリケーション側で独自のスケジューリングメカニズムを実装し、同じOSスレッドで異なる要求を実行する軽量メカニズムが存在する。ファイバー(fiber、軽量スレッド)はユーザーモードバージョンのスレッドで、アプリケーションが独自のスケジューリングロジックでどのファイバーを実行するかを選べる(Windowsがサポート)。コルーチン(co-routine)はユーザーモードアプリケーションがスケジューリングできるサブルーチンで、ファイバーよりもさらに軽量である。イベントベースの並行実行は、プログラムを一連のイベントハンドラに分割し、実行できるイベントハンドラをキューに基づいて決定する方式で、Node.jsランタイムは単一のイベントワーカースレッドを使ってこれを実現している(そのスレッドは1個のCPUでしか実行できないためボトルネックになりうる)。Golangランタイムは、OSスレッドのプールを準備した上でgoroutine(コルーチン)を使い、goroutineがブロックする呼び出しをすると、そのスレッドの他のgoroutineを自動的に別スレッドへ移して実行するようスケジューリングする。(Source: [[@2023__OReillyJapan__詳解 システム・パフォーマンス 第2版 - Chapter 5 アプリケーション]] §5.2.5) マルチスレッドプログラミングには広く使われる3つのモデルがある。(1) サービススレッドプール(service thread pool): ネットワーク要求にサービスを提供するスレッドのプールを用意し、個々のスレッドが同時に1つのクライアント接続にサービスを提供する。(2) CPUスレッドプール(CPU thread pool): CPUごとに1個のスレッドを作る。ビデオエンコーディングなどの時間のかかるバッチ処理で広く使われる。(3) 段階的イベント駆動型アーキテクチャ(Staged event-driven architecture, SEDA): アプリケーションの要求をステージに分解し、そのステージを1個以上のスレッドのプールで処理する。マルチスレッドプログラムはプロセスと同じアドレス空間を共有するため、コストの高いIPC(プロセス間通信)を介さずに複数のスレッドが直接同じメモリを読み書きできるが、そのぶんデータ破壊を防ぐための[[同期プリミティブ]]が必要になる。(Source: [[@2023__OReillyJapan__詳解 システム・パフォーマンス 第2版 - Chapter 5 アプリケーション]] §5.2.5) ## 横断的知見 - (このconceptは本ソース1件からの立ち上げ。今後、別の並行処理系ソース(言語ランタイム論・分散システム論等)との突き合わせで横断的知見を蓄積する。) ## 未解決の問い - サービススレッドプール・CPUスレッドプール・SEDAの3モデルは、どのような負荷特性(要求サイズの分布・I/Oバウンド度合い)のもとでそれぞれ有利になるか、定量的な比較実験を行った一次資料はあるか。 - Golangのgoroutineスケジューラ(M:Nモデル)と、Node.jsの単一イベントワーカースレッドモデルは、CPUバウンドワークロードに対する挙動がどう異なるか。 - ファイバー・コルーチンといったユーザーモード並行実行機構が、OSスレッドスケジューラのコンテキストスイッチオーバーヘッドをどの程度削減するかを実測したベンチマークは本wikiに未収載。 ## 関連 - ソース: [[@2023__OReillyJapan__詳解 システム・パフォーマンス 第2版 - Chapter 5 アプリケーション]](§5.2.5) - 書籍: [[詳解 システム・パフォーマンス 第2版]] - 概念: [[同期プリミティブ]] / [[スレッド状態分析]] - エンティティ: [[Brendan Gregg]] ## 出典 - [[@2023__OReillyJapan__詳解 システム・パフォーマンス 第2版 - Chapter 5 アプリケーション]](§5.2.5 並行実行と並列処理)