1

配列「A」と同様に定義された(一種の)多次元配列をどのように転送しますか(つまり

int********* A;

) C の多次元配列をCUDA GPU に効率的に 1 次元に変換しますか? ありがとう!

4

1 に答える 1

4

質問を編集していただいたので、回答を編集します。このような配列 (* ********A) を作成するのはかなり困難です。ネスト レベルが配列の次元と等しい、malloc を使用したネストされたループが必要です。そうは言っても、応答は私がすでに以下に投稿したものと似ています。途中で cudaMalloc と cudaMemcpy を実行しているネストされたループの並列セットがあるか、またはすべてを線形化し、1 つのステップで転送します。2 次元配列の場合、どちらかのアプローチを提案することを検討できます。N 次元配列の場合、最初の方法は、この一連の SO の質問に示されているように、単純に狂気です。. したがって、デバイスに転送する前に、大きな次元の可変行配列を線形化する必要があると思います。線形化の方法は、あなたが参照している前の質問で尋ねられており、ここでの私の回答の範囲外です。線形化されると、転送操作は簡単で、単一の cudaMalloc/cudaMemcpy 操作で実行できます。


おそらく、個々の行のサイズが異なる (したがって、個別に malloc される) 配列を参照している可能性があります。2つの選択肢があると思います:

  1. 対応する cudaMalloc (各行 malloc 用) と cudaMemcpy (各 cudaMalloc 用) を使用して、行を個別に転送します。
  2. ホスト メモリ内の行を結合 (パック) して、データ セット全体のサイズ (行サイズの合計) である 1 つの連続したブロックを作成します。次に、単一の cudaMemcpy を使用して、この「パックされた」配列を 1 ステップでデバイスに転送します。転送効率の観点からは、これが最も効率的です。

どちらの場合でも、アクセス メカニズムを慎重に検討して、配列を GPU で便利に利用できるようにする必要があります。この点では、最初の方法の方が簡単かもしれません。行ごとにポインターが自動的に作成されるからです。2 番目の方法では、ホスト上の行ポインターと一致するように、デバイス上に一連のポインターを作成する必要がある場合があります。さらに、デバイスのアクセス メカニズムはホストと同様である必要があります。これは、どちらも一連の行ポインターを使用して配列にアクセスするためです。

代わりに、通常の多次元配列 (a[dim1][dim2][dim3]...) を参照している場合、それは既にすべてメモリ内で連続しており、単一のポインターでアクセスできるため、簡単です。元の可変行配列を、列数が最も長い行と等しい通常の多次元配列として作り直す場合 (したがって、他の行で使用されていない要素を残す場合)、代わりにこの手法を利用できます。未使用の要素を転送しているため、これは非効率的ですが、配列へのアクセスは簡単です。

本当に疎行列がある場合は、疎行列の表現方法も検討する必要があります。 cuspは、GPU でこれらを処理および操作するための 1 つの方法です。

この答えも興味深いかもしれません。

于 2012-10-23T18:35:05.380 に答える