1

CUDA のスレッド/ブロックと配列について何度も読んだことがありますが、CUDA がカーネル関数のマルチスレッドの実行を開始する方法とタイミングをまだ理解していません。ホストがカーネル関数を呼び出すとき、またはカーネル関数内。

たとえば、この例があります。配列を単純に転置するだけです。(したがって、この配列から別の配列に値をコピーするだけです)。

__global__
void transpose(float* in, float* out, uint width) {
    uint tx = blockIdx.x * blockDim.x + threadIdx.x;
    uint ty = blockIdx.y * blockDim.y + threadIdx.y;
    out[tx * width + ty] = in[ty * width + tx];
}

int main(int args, char** vargs) {
    /*const int HEIGHT = 1024;
    const int WIDTH = 1024;
    const int SIZE = WIDTH * HEIGHT * sizeof(float);
    dim3 bDim(16, 16);
    dim3 gDim(WIDTH / bDim.x, HEIGHT / bDim.y);
    float* M = (float*)malloc(SIZE);
    for (int i = 0; i < HEIGHT * WIDTH; i++) { M[i] = i; }
    float* Md = NULL;
    cudaMalloc((void**)&Md, SIZE);
    cudaMemcpy(Md,M, SIZE, cudaMemcpyHostToDevice);
    float* Bd = NULL;
    cudaMalloc((void**)&Bd, SIZE); */
    transpose<<<gDim, bDim>>>(Md, Bd, WIDTH);   // CALLING FUNCTION TRANSPOSE
    cudaMemcpy(M,Bd, SIZE, cudaMemcpyDeviceToHost);
    return 0;
}

(重要ではないすべての行にコメントしました。関数を呼び出す行を転置するだけです)

function を呼び出す行を除く、関数 main のすべての行を理解しましたtranpose。function を呼び出すとtranspose<<<gDim, bDim>>>(Md, Bd, WIDTH)、CUDA は自動的に配列の各要素を 1 つのスレッド (およびブロック) に割り当てます。また、「1 回限り」の転置を呼び出すと、CUDA はスレッドgDim * bDim上で実行時間を転置しgDim * bDimます。

Javaのマルチスレッドが苦手なので、この点がとてももどかしいです:(教えてください。

ありがとう :)

4

1 に答える 1

5

あなたの理解は本質的に正しいです。

transpose関数ではなく、CUDA カーネルです。通常の関数を呼び出すと、一度だけ実行されます。ただし、カーネルを 1 回起動すると、CUDA は自動的にカーネル内のコードを何度も実行します。CUDA は、多くのスレッドを開始することでこれを行います。各スレッドは、カーネル内のコードを 1 回実行します。三重括弧 ( ) 内の数字<<< >>>は、カーネル実行構成と呼ばれます。CUDA によって起動されるスレッドの数を決定し、スレッド間の関係を指定します。

開始されるスレッドの数は、三重括弧内のグリッドおよびブロック ディメンションのすべての値を乗算することによって計算されます。たとえば、この例では、スレッドの数は 1,048,576 (16 * 16 * 64 * 64) になります。

各スレッドは、いくつかの変数を読み取って、それがどのスレッドであるかを調べることができます。これらは、カーネルの上部にあるblockIdxand構造です。threadIdx値は、カーネル実行構成の値を反映しています。したがって、16 x 16 のグリッド構成でカーネルを実行すると (dim3三重括弧の最初の部分は、スレッドが取得され、それぞれが構造内の値と値を読み取るxy、0と 0 の間blockIdxのすべての可能な組み合わせが取得されます)。 15.xy

ご覧のとおり、CUDA は配列要素やカーネル固有のその他のデータ構造について何も知りません。スレッド、スレッド インデックス、およびブロック インデックスを処理するだけです。次に、これらのインデックスを使用して、特定のスレッドが何をすべきか (特に、アプリケーション固有のデータのどの値を処理する必要があるか) を決定します。

于 2012-12-12T04:02:13.777 に答える