クリーム色の背景、色付き表示、高コントラスト、大きな文字のほうが読みやすいですか?配色と文字を選ぶと、すべてのページに一度で反映されます。

無料レッスン

計算とメモリ、どちらが足を引っ張るか

このレッスンのあとで: 運ぶ時間と計算の時間を比べて、仕事が計算とメモリのどちらに縛られるかを言える。

55分のレッスンコマンド2件並列計算ラボ:GPU を使わずに GPU の考え方を JupyterLab で

仕事の速さは、計算かメモリの遅い方で決まる

ボトルネックとは、仕事全体の速さを決めてしまう、いちばん遅い部分のことです。GPUでは、計算よりも、データを運ぶ時間の方が長くかかる仕事がよくあります。

このレッスンでは、運ぶ時間と計算の時間を見積もって、どちらが足を引っ張るかを判断します。ラボにGPUはなく、仮の装置の算数で確かめます。

このレッスンのゴール

メモ

運ぶ時間と計算の時間を比べて、仕事が計算とメモリのどちらに縛られるかを言える。

重要な言葉

ことばいみれい
ボトルネック全体の速さを決める、いちばん遅い部分
帯域幅1秒に運べるデータの量毎秒500ギガバイト
計算の速さ1秒にできる計算の回数
転送データをメモリや装置の間で運ぶこと
連続したアクセス隣どうしの場所を、まとめて読むこと

学生が入力するセルは、このプレビューでは空白です。

装置には、運ぶ速さと計算の速さの2つの限界がある

仕事をするには、データをメモリから運び、計算し、結果を書き戻します。運ぶ速さと、計算の速さは別々の限界です。

運ぶ時間は、バイト数 ÷ 帯域幅です。計算の時間は、計算の回数 ÷ 計算の速さです。長い方が、その仕事の時間を決めます。

仮の装置で、2つの仕事を比べる

仕事運ぶバイト数運ぶ時間計算の時間足を引っ張るもの
ベクトルの足し算 (1000万個)120000000240.0マイクロ秒1.0マイクロ秒メモリ
行列の掛け算 (1000×1000)1200000024.0マイクロ秒200.0マイクロ秒計算

学生が入力するセルは、このプレビューでは空白です。

運ぶ時間と計算の時間を見積もる

コード: python
# 100万個のベクトルの足し算を、仮の装置で見積もります。
bandwidth = 500 * 10**9      # 1秒に運べるバイト数
rate = 10 * 10**12           # 1秒にできる足し算の数
n = 1000000
moved = 3 * n * 4            # 2つ読んで1つ書く、1個4バイト
memory_us = moved / bandwidth * 10**6
compute_us = n / rate * 10**6
print("運ぶのにかかる時間 (マイクロ秒):", round(memory_us, 1))
print("計算にかかる時間 (マイクロ秒):", round(compute_us, 1))
if memory_us > compute_us:
    print("足を引っ張るのは: メモリ")
else:
    print("足を引っ張るのは: 計算")
# n を 10 倍にして、2つの時間がどう変わるか見ましょう。

隣どうしを読めば、メモリは速く使える

メモリは、32バイトなどの線の単位でまとめて読まれます。8つのスレッドが隣どうしの数を読めば、線は1本で済みます。

8個おきに読むと、線は8本要ります。同じ8つの数でも、読む本数が違います。スレッドは、隣どうしを読むように並べます。

よくある間違い

注意

計算の速い装置なら、どの仕事も速くなると思いがちです。ベクトルの足し算のように、計算が少なく運ぶ量が多い仕事では、メモリが縛ります。速くするには、運ぶ量を減らす工夫が先です。

ラボの端末で、運ぶ時間と読む場所を見る

ラボにGPUはありません。1つ目のスクリプトは、仮の装置の算数です。毎秒500ギガバイト、毎秒10テラの足し算という、決めた数で計算します。

出力には英語の単語が出ます。bytes moved は運んだバイト数、limited by は足を引っ張るものです。時間は測りません。2つ目は、読む場所の違いを数えます。

運ぶ時間と計算の時間を比べる

コマンド
docker exec jupyter python3 steps/transfer.py

ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。

読む場所の違いを見る

コマンド
docker exec jupyter python3 steps/coalesce.py

ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。

さらに挑戦: 運ぶ回数を減らす

2つのベクトルを足して、さらに2倍するとします。2回に分けると、メモリを2往復します。

1回でまとめて計算できれば、運ぶバイト数はどうなるでしょうか。メモリが縛る仕事で、この工夫が効く理由を、自分の言葉で説明しましょう。

このラボとソースについて: 並列計算ラボ:GPU を使わずに GPU の考え方を JupyterLab で

授業で使いますか?このモジュールを学生に割り当てると、教員用ガイド、自動採点つきの課題、学生ごとのラボを使えます。