TL;DR
- 並行処理には、スループットの向上と応答性の向上という 2 つのメリットがある。
- Go は軽量なゴルーチンを使い、並列実行はランタイムとハードウェアに任せる。プログラマは正しい並行プログラムを書くことに注力する。
- 性能のスケーリングは、アムダールの法則とグスタフソンの法則で考える。
内容
並行処理のメリット
1 つ目のメリットはスループットの向上である。マルチコアプロセッサ上でタスクを並列に処理すれば、スループットが上がる。ただし、プロセッサを最大限に使うようにコードを書いた場合に限る。プロセッサが 1 つしかなくても、I/O の待ち時間を有効に使えばスループットは上がる。
2 つ目のメリットは応答性の向上である。並行処理では、タスクの終了を待たずにユーザへ応答できる。これはマルチコアかどうかに関係ない。
Go での並行処理
Go は、並行処理の基本単位を表すのにゴルーチンという軽量な構造を使う。Go の基本的な考え方は「並列処理はランタイムとハードウェアに任せ、プログラマは正しい並行プログラムを書くことに注力するべきである」というものだ。この原則に従えば、何かを並行して実行したいときに、資源の割り当てを気にせずゴルーチンを作れる。プログラムは、実行されるハードウェアや環境に応じてスケールする。
Go では、2 つの方式からアプリケーションの組み立て方を選べる。1 つはメモリ共有で使われる古典的な基本操作(Mutex や条件変数)である。もう 1 つは CSP 方式のモデル(チャネル)である。CSP モデルでは、分離されたゴルーチンがチャネルで通信と同期を行うので、競合状態のリスクを減らせる。ただし、問題によっては古典的な基本操作のほうが良いパフォーマンスや結果を得られる。
性能のスケーリング
アムダールの法則によれば、固定サイズの問題では、性能のスケーラビリティは逐次処理の部分に制限される。
一方、グスタフソンの法則によれば、余分な資源を効率よく使う方法を見つけられれば、逐次処理に制限されることはなく、性能は上がり続ける。ただし、逐次処理の部分が問題の大きさに比例しないことが前提である。