1

それが可能かどうか疑問に思っていました.CUDAのスレッドを使用して配列からセルを読み取る最良の方法は何ですか. 私が意味することを簡単にするために、これは例です:

{1,2,3,4,5,6,...} という配列があり、主にそのサイズに応じて、各スレッドが配列の n 個のセルを読み取るようにしたいと考えています。

私はいくつかのことを試してきましたが、うまくいかないようですので、誰かがそれを行う(正しい)方法を指摘できれば、それは素晴らしいことです.

ありがとうございました。

4

2 に答える 2

3

一般に、連続するスレッドが連続する配列インデックスを読み取れるようにする必要があります。これを行うと、「結合された」メモリ トランザクションが発生します。簡単に考えると、32 個のスレッドが物理的に並列に実行されていて、それらすべてが 1 つのロードを実行し、32 個のロードすべてが同じキャッシュ ラインに分類される場合、単一のメモリ アクセスを実行してキャッシュ ラインを埋めることができます。 、32個の個別のものではなく。

したがって、次のように、各スレッドnがスレッドの数だけストライドされたセルにアクセスするようにする必要があります (入力データがfloatarrayにあると仮定しますdata)。

int idx = blockDim.x * blockIdx.x + threadIdx.x;
int stride = blockDim.x * gridDim.x;
for (int i = idx; i < numElements; i += stride) {
  float element = data[i];
  process(element);
}

アルゴリズムで各スレッドがn連続したデータ要素を読み取る必要がある場合は、結合されていないロードが発生し、コストが大幅に高くなります。この場合、このタイプのアクセスが不要になるように、アルゴリズムを再設計することを検討します。

于 2012-11-22T11:25:28.580 に答える
0

必要がある:

スレッドは n 個の次の数字を見る必要があります

したがって、次を使用できます。

#define N 2
#define NTHREAD 1024
#define ARRAYSIZE N*NTHREAD

// develop the kernel as:
__global__ void accessArray(int *array){
    int tid = blockDim.x * blockIdx.x + threadIdx.x;
    int startId = tid*N;

    // access thread's stride
    for(int i=0; i<N; i++){
        array[startId+i]=tid;
    }
}
// call the kernel by:
accessArray<<<NTHREAD/256, 256>>>(d_array);

をダンプして、arrayそれがスレッドの動作方法であるかどうかを確認してください。

完全なコード:

#include <cuda.h>
#include <stdio.h>


#define N 2
#define NTHREAD 1024
#define ARRAYSIZE N*NTHREAD

// develop the kernel as:
__global__ void accessArray(int *array){
    int tid = blockDim.x * blockIdx.x + threadIdx.x;
    int startId = tid*N;

    // access thread's stride
    for(int i=0; i<N; i++){
        array[startId+i]=tid;
    }
}

int  main()
{
    int h_array[ARRAYSIZE];
    int *d_array;
    size_t memsize= ARRAYSIZE * sizeof(float);

    for (int i=0; i< ARRAYSIZE; i++) {
        h_array[i] = 0;
    }

    cudaMalloc(&d_array, memsize);
    cudaMemcpy(d_array, h_array, memsize,  cudaMemcpyHostToDevice);

    accessArray<<<NTHREAD/256, 256>>>(d_array);
    cudaMemcpy(h_array, d_array, memsize,  cudaMemcpyDeviceToHost);

    for (int i=0; i<ARRAYSIZE; i++)
        printf("A[%d] => %d\n",i,h_array[i]);

    cudaFree(d_array);
}
于 2012-11-22T20:17:38.030 に答える