1

CUDA ライブラリを使用してスパイキング ニューラル ネットワークを実装していますが、次の点についてどのように進めればよいかよくわかりません。

  1. 多くの異なる配列へのメモリ (cudaMalloc) の割り当て。これまでは、cudaMalloc を「手動で」使用するだけで十分でした。10 個以上の配列を作成する必要がなかったためです。ただし、ポインタを作成し、何千もの配列にメモリを割り当てる必要があります。

  2. これらの配列のそれぞれに割り当てるメモリの量を決定する方法。配列の高さは 3 (シナプス後ニューロン ID 用の 1 行、シナプス後ニューロンのシナプス数用の 1 行、およびそのシナプスの有効性用の 1 行) ですが、長さは未定であり、時間の経過とともに変化します。発信シナプスの数。

CUDA での動的メモリ割り当ては非常に遅いと聞いたので、各配列に必要な最大メモリを割り当てるという考えをもてあそびましたが、ニューロンごとの出力シナプスの数は 100 から 10,000 まで変化するので、これは実行不可能だと思いました。私は1000個のニューロンを持っています。

GPU 上の多くの配列にメモリを割り当てる方法、および/または上記のタスクのために高速で動的なメモリ割り当てをコーディングする方法について誰かが私にアドバイスしてくれたら、私は非常に感謝しています。

前もって感謝します!

4

1 に答える 1

1

cudaMalloc本当にこれをやりたい場合は、何度でも呼び出すことができます。ただし、それはおそらく良い考えではありません。代わりに、ブロック内の隣接するスレッドが可能な限り RAM の隣接する要素にアクセスできるようにメモリをレイアウトする方法を考えてみてください。

これが問題になる可能性が高い理由は、スレッドが一度に 32 のグループで実行されるためです (ワープ)。NVidia のメモリ コントローラは非常にスマートであるため、隣接するスレッドが RAM の隣接するバイトを要求した場合、それらのロードを効率的に実行できる単一の要求にまとめます。対照的に、ワープ内の各スレッドがランダムなメモリ位置にアクセスしている場合、ワープ全体は 32 個のメモリ要求が完了するまで待機する必要があります。さらに、カードのメモリへの読み取りと書き込みは一度にキャッシュ ライン全体で行われるため、キャッシュから削除される前に読み取られたすべての RAM をスレッドが使用しないと、メモリ帯域幅が浪費されます。スレッド ブロック内でコヒーレントなメモリ アクセスを最適化しない場合は、10 倍から 100 倍の速度低下が予想されます。

(補足: 上記の議論は G80 以降のカードにも当てはまります。第 1 世代の CUDA ハードウェア (G80) はさらにうるさいものでした。また、プログラマーが合体動作を望む場合は、整列されたメモリ要求が必要でした。)

于 2013-03-24T19:39:34.647 に答える