0

私は次のような構造を持っています

struct Point
{
 int x;
 int y;
float val;
}

この構造体をスパース行列の表現に使用し(CUSPARSEとCUSPを認識していますが、推力を使用していくつかのテストを実行する予定です)、推力アルゴリズムを使用して操作を実行します。

私がCUDAプログラミングチュートリアルで学んだことから、より良いメモリ合体のために構造体の配列ではなく配列の構造体を使用することを常にお勧めします。

その場合、上記の構造体を使用してdevice_vector内にゼロ以外(数百万のオーダー)を格納すると、このdevice_vectorは推力アルゴリズムで作業しているときにGPU内で非整列メモリアクセスを使用しますか?

このdevice_vector内の不規則なストライドにアクセスし、複数の関数オブジェクトを渡すことによってアルゴリズム操作を実行する必要があるかもしれないので、これを尋ねます。

配列の構造体で動作するカスタムカーネルと同じくらい効率的でしょうか?

ありがとう。

4

1 に答える 1

4

NVIDIA CUDA デバイスは、結合されたメモリ アクセス パターンを想定して、4、8、および 16 バイトの構造に効率的にアクセスできます。この目的のために、CUDA ヘッダーは、使用できる構造体、、、、などをint2定義します。それらは効率的な配置を持つように定義されているため、カスタム Point 構造体の代わりに、使用することをお勧めしますint4float2float4

typedef int2 Point;

これらの小さな構造体の配列へのすべてのメモリ アクセスがワープ内のスレッド間でシーケンシャル (合体など) であり、各構造体要素のすべてのデータが読み取り/書き込みを行うスレッドによって使用される場合、このタイプの AOS アクセスは非常に効率的です。実際、このようなベクトル構造体を使用すると、処理中のメモリ トランザクションが増加するため、多くの場合、スカラ データ アクセスよりもメモリ スループットが高くなります。

Thrust はzip_iterator、SOA データを AOS データであるかのように操作する利便性と (コーディング) 効率を具体的に提供します。したがって、単純な CUDA C++ では小さな構造体が効率的ですが、Thrust を使用する場合は、代わりにdevice_vector構造体メンバーごとに個別に使用することを選択し、zip_iterator呼び出し前transformおよび他の推力アルゴリズムを使用してそれらをまとめて圧縮することができます。Thrust サンプル コードには、この例が含まれています。

于 2012-07-02T06:42:55.230 に答える