Skip to content

Instantly share code, notes, and snippets.

@takagi
Created March 4, 2016 04:08
Show Gist options
  • Save takagi/3e4f3a8678a8f74e852e to your computer and use it in GitHub Desktop.
Save takagi/3e4f3a8678a8f74e852e to your computer and use it in GitHub Desktop.
sph
https://github.com/takagi/cl-cuda/tree/issue/49.symbol-macro
・時間を食う処理は、update-density と update-force で、全体の 90% 以上
・アルゴリズムは所与としたとき、GPU の使い方のレベルで高速化する余地はあるか?
 →メモリアクセスにあまり局所性がなさそう
 →グローバルメモリへのアクセスが律速なので、それ以上はもうやりようがない?
・グリッドやブロックの割当てはどのようにやるもの?
 →影響するパラメータを変えるたびに手計算してハードコードしているがそういうもの?
・粒子インデックスの計算はどのようにやるもの?
 →グリッドやブロックの割当て方に影響を受けるがそういうもの?
 →[0,n) でディスパッチしてくれたらいいのに
@gos-k
Copy link

gos-k commented Mar 4, 2016

・グリッドやブロックの割当てはどのようにやるもの?
 →影響するパラメータを変えるたびに手計算してハードコードしているがそういうもの?

用語的に グリッドやブロック ではなく、ブロックやスレッド ですかね。(blockDimがスレッドの数でなんか分かりずらいですが。。。)
アルゴリズムや対象のGPUによってブロックやスレッドの役割とか次元をどうするかは変わりますし、数値は実測してハードコードします。
最内ループの演算を微妙に変えた結果、使用するレジスタ数が変わってオキュパンシーが変化することにより、blockDimを変更することもあります。

・粒子インデックスの計算はどのようにやるもの?
 →グリッドやブロックの割当て方に影響を受けるがそういうもの?

要素数がgridDim, blockDimで指定できる範囲内ならば、基本はsphのコードのようにしていて、割り当て方の影響を受けます。
チューニングの結果としてblockDimが固定値になることが多いので、呼び出し側で gridDim = (n / blockDim) + ((n % blockDim == 0) ? 0 + 1) みたいなことをやったりする。

 →[0,n) でディスパッチしてくれたらいいのに

OpenCLではそんなIFになりましたね。。。

@gos-k
Copy link

gos-k commented Mar 10, 2016

pressure-termvisconsity-termrhoi でアクセスしており2回のロードが行われます。
update-force でロードして各関数に渡すようにした方が良いです。
(デバイスメモリがキャッシュされるアーキテクチャだと速度差はないかも)

defglobal は毎回ロードが発生しますが、constant にするとキャッシュが効くので構文を追加した方が良いです。
(デバイスメモリがキャッシュされるアーキテクチャだと速度差はないかも)

浮動小数点の即値が無印でdoubleのまま出ており、Common Lisp側でsingle floatを指定したら、出力側の即値にfが付くように構文を変更した方が良いです。

現状 with-particle-index が1スレッド1インデックスとなっているため全てのデバイスメモリをランダムアクセスするが、neighbor-map へのアクセスはリニアなので、with-particle-index を1ブロック1インデックスとし neighbor-map のアクセスをコアレスにし結果をリダクション加算すると、
加算順序の入れ替えによる誤差は出るものの高速化する可能性があります。
(これ本当のところどうなるかやってみないとよく分からない)

これに加えて、さらに1ブロックnインデックスの処理を行うようにし、各ループの計算結果を共有メモリ保持して置き、一定量たまったら書き出すとコアレスアクセスになって速いです。

両方の対応をすると一つのカーネルの中で、各スレッドが l を基準に動く時と i を基準にで動く時が出てきて大分混乱はします。

update-densitynorm 計算をし poly6-kernel でも norm 計算をしていますが、これは再計算している可能性があるので変数に入れて再利用した方が速いです。

@takagi
Copy link
Author

takagi commented Mar 11, 2016

defglobal は毎回ロードが発生しますが、constant にするとキャッシュが効くので構文を追加した方が良いです。
(デバイスメモリがキャッシュされるアーキテクチャだと速度差はないかも)

takagi/cl-cuda@be9f065

浮動小数点の即値が無印でdoubleのまま出ており、Common Lisp側でsingle floatを指定したら、出力側の即値にfが付くように構文を変更した方が良いです。

takagi/cl-cuda@60afc2e

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment