CUDAのプログラミングの覚書 [CUDA]
CUDAのコードを書いていて、たまに理解しがたいエラーがでることがあるが、
大抵はメモリ周りのエラーでホストからデバイスへの転送がうまく行ってないことが多い。
Fermiからデバイス側でprintfが使えるようになったのは非常に助かるようになった。
とはいえ、同じ間違いを何度も繰り返してしまうので、ちょっとメモしておく。
1)構造体のサイズに注意。
ホスト側とデバイス側で同じ構造体を扱っているのに、転送でエラーになることがある。
多くの場合で、ホストとデバイス側でサイズが異なっている。構造体の中身を変更したときなどに起こる。一旦プロジェクトをクリーンして再ビルドをすればうまく行くことが多い。
2)ホスト側にデバイスの情報を置き忘れ。
カーネルの引数にポインタを持ってくる場合に、デバイス側のメモリのポインタを保持していない、
またはホスト側のポインタを与えてエラーになることが多い。
3)CUDAのコードを実行すると数回に1回の割合でうまく動作してしまう場合はメモリ周りに問題がある。しっかしデバッグをしないとあとで痛い目にあう。
4)デバイス側のメモリを確保しても必ずしもデータは0クリアされていない。また、First Touchの問題か、エラーがでることがあるので、CudaMemsetで初期化を忘れない。
5)Tookitの出来によってパフォーマンスが変わる。例としては4.0=>4.2で一割ほど改善があった。
6)シェアードメモリをexternで使う場合はカーネル引数を忘れずに。
7)Threadはあまり意識しなくてもいいが、BlockとGridは意識する。
8)なるべく多くの処理をCUDAデバイス側でやらないとパフォーマンスが得にくい。
ちょっと思っただけでもこのくらいか。
大抵はメモリ周りのエラーでホストからデバイスへの転送がうまく行ってないことが多い。
Fermiからデバイス側でprintfが使えるようになったのは非常に助かるようになった。
とはいえ、同じ間違いを何度も繰り返してしまうので、ちょっとメモしておく。
1)構造体のサイズに注意。
ホスト側とデバイス側で同じ構造体を扱っているのに、転送でエラーになることがある。
多くの場合で、ホストとデバイス側でサイズが異なっている。構造体の中身を変更したときなどに起こる。一旦プロジェクトをクリーンして再ビルドをすればうまく行くことが多い。
2)ホスト側にデバイスの情報を置き忘れ。
カーネルの引数にポインタを持ってくる場合に、デバイス側のメモリのポインタを保持していない、
またはホスト側のポインタを与えてエラーになることが多い。
3)CUDAのコードを実行すると数回に1回の割合でうまく動作してしまう場合はメモリ周りに問題がある。しっかしデバッグをしないとあとで痛い目にあう。
4)デバイス側のメモリを確保しても必ずしもデータは0クリアされていない。また、First Touchの問題か、エラーがでることがあるので、CudaMemsetで初期化を忘れない。
5)Tookitの出来によってパフォーマンスが変わる。例としては4.0=>4.2で一割ほど改善があった。
6)シェアードメモリをexternで使う場合はカーネル引数を忘れずに。
7)Threadはあまり意識しなくてもいいが、BlockとGridは意識する。
8)なるべく多くの処理をCUDAデバイス側でやらないとパフォーマンスが得にくい。
ちょっと思っただけでもこのくらいか。
コメント 0