NAS Parallelベンチマーク
をテンプレートにして作成
[
トップ
] [
新規
|
一覧
|
単語検索
|
最終更新
|
ヘルプ
|
ログイン
]
開始行:
[[並列グループ各種情報]]
* 概要 [#s6448c66]
並列分野の有名なベンチマークプログラム集。
NASAのサイトから入手できるが、登録が必要なのでとりあえず...
(最新版ではないが)/home/ohno/gpu/NAS/NPB3.3.1/下をコピー。
逐次版(SER)の他、MPI, OpenMP版(MPI, OMP)が提供されている。
ビルドするには、ビルドしたい版のディレクトリ(例: NPB3.3-S...
make EP CLASS=S
のようにベンチマークプログラム名とクラス
(問題のサイズ。Sが最小のテスト用で、
評価用はA, B, と順に大きくなる)を指定する。
コンパイルされた実行ファイルは
bin
下にベンチマーク・クラス毎に異なるファイル名で
格納されるので、
bin/ep.S.x
のようにして実行する。
スパコンなどを想定したベンチマークなので、
計算時間はまだしも、使用メモリ量に注意。
* 移植 [#t2a00d30]
IS, DCはCだがその他はすべてFORTRANで書かれている。
また、
CUDA版は現在一般的に提供されているものはないもよう。
とりあえずEPはCおよびCUDAに移植してある。
その他のものを移植する場合のヒントについては[[FORTRANから...
* EP (Embarrassingly Parallel) [#d44bad94]
** 概要 [#g1f72e17]
疑似乱数を大量に生成する。
結果収集時に通信を必要とする以外は並列処理間の依存がまっ...
スケーラブルで高い並列度が得られる(はず)。
また、大量の浮動小数点数(double)演算を行う。
問題サイズを規定するパラメータM(CLASS Sで24, CLASS Mで28)...
2^M個の乱数ペアを生成し、その後で全ペアに対してチェック?...
一個の乱数は簡単な式により定数時間で求めるため、
計算量はO(2^M)である。
必要メモリ量も全乱数ペアを同時に生成するとO(2^M)であるが、
逐次版ではループの反復毎に2^MKずつ生成しているため、
O(2^MK)で済んでいる。なお、MKは変更可能とコメントされてお...
オリジナルの値は16である。
**CUDA版の基本構造 [#ad37a279]
主要な処理はオリジナル版でのdo 150ループ(kループ)内に書か...
このループは反復間依存がないため並列化可能。
そのまま並列化すると1ループ分の処理が1スレッドとなり、
ループ回数(nn=2^(M-MK))分の並列度が得られる。
その代わり、xのサイズをnn倍しておく必要がある。
各スレッド内ではd_vranlc()を1回呼び出して、
一気に2*2^MK個の乱数を生成する。
これらの乱数は一つの乱数系列なので、d_vranlc()内は並列化...
なお、並列単位毎に独立した乱数系列を使うと逐次版と結果が...
kループ内で毎回starting seedと呼ばれるt1を求めることで解...
おそらくプログラム全体で一つの乱数系列を使用しており、
ループ毎に系列中の今回使うべき範囲の先頭に合わせてstatic...
思われる。
CUDAでの並列化は、kループ内の処理をカーネル関数化し、
ループ回数分のスレッドを生成することで行っている。
しかし、単純にループ回数分の並列化を行うと
乱数を格納する配列変数xのメモリ消費量は
sizeof(double) x 2 x 2^M
となり、CLASS Sで256MB, CLASS Aで4GBとなる。
したがって、4GBしかメモリを積んでいないGTX680ではCLASS A...
6GBのTeslaやTitanでもCLASS B以上は動作しない。
そこで、kループを完全に除去せず、問題空間全体を複数に等分...
各分割空間毎に並列実行するようにした。
具体的には新たにマクロMIを導入し、問題空間全体を2^MKに等...
この結果、x配列はループ毎に再利用されるから、
サイズは上記の消費量の1/(2^MK)で済む。
たとえばMI=3 (8回ループ)にすれば、CLASS Bの問題をGTX680上...
配列x上に乱数を格納した後は、乱数を順にアクセスし、q, sx,...
sx, syはスレッドローカルなスカラー値なので局所変数にして...
最後にグローバルメモリ上のスレッド数分の配列に書き込んで...
** SM内シェアードメモリの利用による高速化 [#dcf0f220]
マクロUSE_SMを定義すると、qをシェアードメモリ上に置くよう...
xは大きすぎるうえにカーネル関数側では各要素に一回ずつ書き...
シェアードメモリの利用には適さない。
qはスレッド毎にNQ要素の配列を必要とするが、
NQ=10なのでブロック内のスレッド数を600程度に抑えればシェ...
載せることができる。q自体へのアクセスはスレッド毎にMK回の...
シェアードメモリの使用により一定の性能向上が期待できる。
qの値はデバイス側で初期化→MK回ランダムアクセスでインクリ...
なので、
シェアードメモリ上の配列
(サイズ:NQ x ブロック内スレッド数)
を初期化・インクリメント処理してから、
カーネル関数の最後にグローバルメモリ上のd_qにコピーしてい...
** コアレシング・アクセスによる高速化 [#q571edad]
マクロCOALESCEDを定義すると、xがコアレシング・アクセスに...
配列xは、素直に実装すると
「1スレッドが使用する一次元配列(2*2^MK)」
×
「一回のカーネル起動で実行するスレッド数」
の2次元配列になる。しかし、スレッド内のアクセス範囲を連続...
(参照の局所性は上がるものの)
ブロック内のスレッド間のアクセスがとびとびになってしまう。
そこで、スレッド内のx要素アクセス時に、
隣接スレッド間で隣の配列要素をアクセスするように配置し、
いわゆる「コアレシング・アクセス」になるようにする。
これを実現するには、上記の2次元配列を転置させればよい。
実際にはCUDAでは動的メモリ確保の都合上一次元配列になって...
xに書き込むd_vlanlc()内と、d_vlanlc()呼び出し後にxの値を...
配列インデックス式を調整し、転置した形で格納されるように...
なお、さらに以下の改良を行うことが考えられるが、比較的効...
現時点では実装していない。
- d_qのコアレシング・アクセス化
CUDA版のqも意味的には二次元配列なので、同様の手法でコア...
しかし、
シェアードメモリ使用版ではスレッド毎にNQ=10回の書き込み...
だけなので、あまり効果が期待できない。
- xのブロック内局所性向上
現在の実装はx全体を単純に転置している。
コアレシング・アクセス上は不都合ないが、
全スレッドでデータをローテーション配置しているため、
ブロック単位で見ると参照が局所化されていない。
したがって、ブロック単位のキャッシュが存在する場合には...
コアレシング・アクセスにするには、
ブロック内(正確にはハーフワープ内)で連続アクセスになっ...
xをまずブロック単位で分割し、各々の中でローテーション配...
この問題を解決できる。
終了行:
[[並列グループ各種情報]]
* 概要 [#s6448c66]
並列分野の有名なベンチマークプログラム集。
NASAのサイトから入手できるが、登録が必要なのでとりあえず...
(最新版ではないが)/home/ohno/gpu/NAS/NPB3.3.1/下をコピー。
逐次版(SER)の他、MPI, OpenMP版(MPI, OMP)が提供されている。
ビルドするには、ビルドしたい版のディレクトリ(例: NPB3.3-S...
make EP CLASS=S
のようにベンチマークプログラム名とクラス
(問題のサイズ。Sが最小のテスト用で、
評価用はA, B, と順に大きくなる)を指定する。
コンパイルされた実行ファイルは
bin
下にベンチマーク・クラス毎に異なるファイル名で
格納されるので、
bin/ep.S.x
のようにして実行する。
スパコンなどを想定したベンチマークなので、
計算時間はまだしも、使用メモリ量に注意。
* 移植 [#t2a00d30]
IS, DCはCだがその他はすべてFORTRANで書かれている。
また、
CUDA版は現在一般的に提供されているものはないもよう。
とりあえずEPはCおよびCUDAに移植してある。
その他のものを移植する場合のヒントについては[[FORTRANから...
* EP (Embarrassingly Parallel) [#d44bad94]
** 概要 [#g1f72e17]
疑似乱数を大量に生成する。
結果収集時に通信を必要とする以外は並列処理間の依存がまっ...
スケーラブルで高い並列度が得られる(はず)。
また、大量の浮動小数点数(double)演算を行う。
問題サイズを規定するパラメータM(CLASS Sで24, CLASS Mで28)...
2^M個の乱数ペアを生成し、その後で全ペアに対してチェック?...
一個の乱数は簡単な式により定数時間で求めるため、
計算量はO(2^M)である。
必要メモリ量も全乱数ペアを同時に生成するとO(2^M)であるが、
逐次版ではループの反復毎に2^MKずつ生成しているため、
O(2^MK)で済んでいる。なお、MKは変更可能とコメントされてお...
オリジナルの値は16である。
**CUDA版の基本構造 [#ad37a279]
主要な処理はオリジナル版でのdo 150ループ(kループ)内に書か...
このループは反復間依存がないため並列化可能。
そのまま並列化すると1ループ分の処理が1スレッドとなり、
ループ回数(nn=2^(M-MK))分の並列度が得られる。
その代わり、xのサイズをnn倍しておく必要がある。
各スレッド内ではd_vranlc()を1回呼び出して、
一気に2*2^MK個の乱数を生成する。
これらの乱数は一つの乱数系列なので、d_vranlc()内は並列化...
なお、並列単位毎に独立した乱数系列を使うと逐次版と結果が...
kループ内で毎回starting seedと呼ばれるt1を求めることで解...
おそらくプログラム全体で一つの乱数系列を使用しており、
ループ毎に系列中の今回使うべき範囲の先頭に合わせてstatic...
思われる。
CUDAでの並列化は、kループ内の処理をカーネル関数化し、
ループ回数分のスレッドを生成することで行っている。
しかし、単純にループ回数分の並列化を行うと
乱数を格納する配列変数xのメモリ消費量は
sizeof(double) x 2 x 2^M
となり、CLASS Sで256MB, CLASS Aで4GBとなる。
したがって、4GBしかメモリを積んでいないGTX680ではCLASS A...
6GBのTeslaやTitanでもCLASS B以上は動作しない。
そこで、kループを完全に除去せず、問題空間全体を複数に等分...
各分割空間毎に並列実行するようにした。
具体的には新たにマクロMIを導入し、問題空間全体を2^MKに等...
この結果、x配列はループ毎に再利用されるから、
サイズは上記の消費量の1/(2^MK)で済む。
たとえばMI=3 (8回ループ)にすれば、CLASS Bの問題をGTX680上...
配列x上に乱数を格納した後は、乱数を順にアクセスし、q, sx,...
sx, syはスレッドローカルなスカラー値なので局所変数にして...
最後にグローバルメモリ上のスレッド数分の配列に書き込んで...
** SM内シェアードメモリの利用による高速化 [#dcf0f220]
マクロUSE_SMを定義すると、qをシェアードメモリ上に置くよう...
xは大きすぎるうえにカーネル関数側では各要素に一回ずつ書き...
シェアードメモリの利用には適さない。
qはスレッド毎にNQ要素の配列を必要とするが、
NQ=10なのでブロック内のスレッド数を600程度に抑えればシェ...
載せることができる。q自体へのアクセスはスレッド毎にMK回の...
シェアードメモリの使用により一定の性能向上が期待できる。
qの値はデバイス側で初期化→MK回ランダムアクセスでインクリ...
なので、
シェアードメモリ上の配列
(サイズ:NQ x ブロック内スレッド数)
を初期化・インクリメント処理してから、
カーネル関数の最後にグローバルメモリ上のd_qにコピーしてい...
** コアレシング・アクセスによる高速化 [#q571edad]
マクロCOALESCEDを定義すると、xがコアレシング・アクセスに...
配列xは、素直に実装すると
「1スレッドが使用する一次元配列(2*2^MK)」
×
「一回のカーネル起動で実行するスレッド数」
の2次元配列になる。しかし、スレッド内のアクセス範囲を連続...
(参照の局所性は上がるものの)
ブロック内のスレッド間のアクセスがとびとびになってしまう。
そこで、スレッド内のx要素アクセス時に、
隣接スレッド間で隣の配列要素をアクセスするように配置し、
いわゆる「コアレシング・アクセス」になるようにする。
これを実現するには、上記の2次元配列を転置させればよい。
実際にはCUDAでは動的メモリ確保の都合上一次元配列になって...
xに書き込むd_vlanlc()内と、d_vlanlc()呼び出し後にxの値を...
配列インデックス式を調整し、転置した形で格納されるように...
なお、さらに以下の改良を行うことが考えられるが、比較的効...
現時点では実装していない。
- d_qのコアレシング・アクセス化
CUDA版のqも意味的には二次元配列なので、同様の手法でコア...
しかし、
シェアードメモリ使用版ではスレッド毎にNQ=10回の書き込み...
だけなので、あまり効果が期待できない。
- xのブロック内局所性向上
現在の実装はx全体を単純に転置している。
コアレシング・アクセス上は不都合ないが、
全スレッドでデータをローテーション配置しているため、
ブロック単位で見ると参照が局所化されていない。
したがって、ブロック単位のキャッシュが存在する場合には...
コアレシング・アクセスにするには、
ブロック内(正確にはハーフワープ内)で連続アクセスになっ...
xをまずブロック単位で分割し、各々の中でローテーション配...
この問題を解決できる。
ページ名: