並列計算とは、仕事を分けて同時に進めること
並列計算とは、1つの仕事をいくつかに分けて、同時に進めることです。人手を増やせば速くなりますが、何倍にもなるとは限りません。
このレッスンでは、何倍速くなるかを、表と式で見積もります。なお、このモジュールのラボにGPUはありません。GPUの土台になる考え方を、ふつうのPythonで確かめます。
このレッスンのゴール
メモ
分けられない部分の割合から、人数を増やしたときの速さの倍率を見積もれる。
重要な言葉
| ことば | いみ | れい |
|---|---|---|
| 並列 | 仕事のいくつかの部分を、同時に進めること | |
| ワーカー | 仕事の一部を受け持つ、1つの処理や1人 | |
| 直列の部分 | 分けられず、順番にやるしかない部分 | |
| 倍率 | 1人のときの時間を、今の時間で割った数 | 10分が4分なら2.5倍 |
| アムダールの法則 | 直列の部分が、倍率の上限を決めるという考え方 |
学生が入力するセルは、このプレビューでは空白です。
仕事には、分けられない部分がある
どんな仕事も、全部を分けられるわけではありません。たとえば、10分かかる申込書の処理のうち、最初の2分は名簿づくりで、1人しかできないとします。
残りの8分は、人数で分けられます。この分けられない2分が、直列の部分です。
人数ごとの時間と倍率
| 人数 | かかる時間 | 倍率 (10分 ÷ 時間) |
|---|---|---|
| 1人 | 2 + 8 = 10分 | 1.0倍 |
| 2人 | 2 + 4 = 6分 | 約1.67倍 |
| 4人 | 2 + 2 = 4分 | 2.5倍 |
| 8人 | 2 + 1 = 3分 | 約3.33倍 |
学生が入力するセルは、このプレビューでは空白です。
倍率は短い式で見積もれる
分けられない割合を s、人数を n とします。倍率は、1 ÷ (s + (1 − s) ÷ n) です。
上の例では s は0.2です。n が4なら、1 ÷ (0.2 + 0.8 ÷ 4) で、2.5倍になります。n をどこまで大きくしても、倍率は 1 ÷ s を超えません。
人数を変えて倍率を計算する
# 直列の割合が0.2のとき、人数ごとの倍率を計算します。
serial = 0.2
for workers in [1, 2, 4, 8, 16]:
speed = 1 / (serial + (1 - serial) / workers)
print(workers, "人:", round(speed, 2), "倍")
# serial を 0.5 に変えて、もう一度実行しましょう。
よくある間違い
注意
8人で分ければ、8倍速くなると思いがちです。8倍になるのは、全部を分けられるときだけです。1割でも直列の部分があれば、8人で約4.7倍にしかなりません。増やす前に、分けられない割合を調べます。
ラボの端末で、倍率の表を出す
ラボにGPUはありません。ふつうのPythonが、倍率の表を出します。下の Run で、端末にコマンドを打ちます。
スクリプトの出力には、英語の単語が出ます。percent の前の数は直列の割合で、あとの4つの数が、1、2、4、8人のときの倍率です。
倍率の表を出す
docker exec jupyter python3 steps/amdahl.pyここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
式を1回だけ計算する
docker exec jupyter python3 -c "print(round(1 / (0.25 + 0.75 / 4), 2))"ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
さらに挑戦: 直列の部分を減らす
人を増やすより、直列の部分を短くする方が、効くことがあります。s が0.2のとき、人数を8人にしても約3.33倍です。
s を0.1に減らして、4人で分けると、約3.08倍です。どちらが得か、自分の言葉で説明しましょう。