私は GPU プログラミングの初心者であり、特定の製品を GPU に移植する価値があるかどうかを判断しようとしています。アルゴリズムの主要なステップの 1 つは、多数のフロベニウス積の計算を必要とします(内積と同様ですが、行列上で、要素ごとの乗算とそれに続く積の合計です)。
データ構造は、すべてを GPU のグローバル メモリに格納できますが、共有メモリには格納できません。私の理解では、GPU は演算強度 (転送されるバイトあたりの浮動小数点演算) が高いときに最高のパフォーマンスを発揮し、ドット積はこの点で (比較的) パフォーマンスが低いということです。私はどれほど貧弱であるかを把握しようとしていますが、詳細のいくつかに混乱しています.
物事を具体的にするために、倍精度エントリの 64x64 行列があると仮定しましょう。(それらは倍精度でなければなりません。) 同様に、行列が正しく配置されるように配置されていると仮定しましょう。明らかに、SM ごとに 1 つのブロックであっても共有メモリに保存するには大きすぎます。したがって、私の考えは、問題を「並べて表示」し、各ブロックに各マトリックスの 16x16 タイルを格納することです。これで、少なくとも 8 つのブロックすべてを一度に操作したり、各製品にスレッドを割り当てたり、各ブロックの合計を計算したりできるようになりました。
私の質問は次のとおりです。
1) FLOPS/バイトとは正確には何を意味しますか? より正確には、このコンテキストでは、倍精度乗算に必要な FLOPS はいくつですか? 答えが 1 の場合、操作ごとに 16 バイトを移動しているように見えますが、これはひどいようです。
2) この計算は、結合されたメモリ読み取りのコンテキストで行われますか? 合体は私を助けますか、それとも私を傷つけますか?
そして、より漠然とした質問:
3) これはやる価値がありますか?
参考までに、私はベンチマークと実験用に GTX 580 と CUDA 4.2 にアクセスできますが、5.0 をインストールすることもできます。また、最近の Nvidia アーキテクチャがいくつかの点でより使いやすい場合、それを知ることも役に立ちますが、アクセスできない場合があります。
アップデート:
私はまだアルゴリズム全体に取り組んでいますが、CPU とやり取りすることなく、行列を生成して GPU のグローバル メモリに保持できると信じる強い理由があります。
合体したメモリアクセスを保証できるという私の仮定を再検討する必要があるかもしれません。行列の一部は、4 次元オブジェクトのスライスです。私の行列の約 3/4 は、明らかに結合された方法で自然にアクセスされますが、残りの 1/4 はそうではありません。ラージ オブジェクトを 2 回格納することで解決できるかもしれませんが、それによって新たな疑問が生じます。
4) 合体メモリのガイドラインは、共有メモリからグローバル メモリへの移動にも適用されますか?