1

私はCUDA光線面交差カーネルを開発しています。

私の飛行機(顔)の構造体は次のようになっているとしましょう。

typedef struct _Face {
    int ID;
    int matID;

    int V1ID;
    int V2ID;
    int V3ID;

    float V1[3];
    float V2[3];
    float V3[3];

    float reflect[3];

    float emmision[3];
    float in[3];
    float out[3];

    int intersects[RAYS];

} Face;

構造体全体を貼り付けたので、サイズがわかります。現在の構成では、 RAYSは625に相当します。次のコードでは、faces配列のサイズが1270(通常は-千)であると想定しています。

今日まで、私は非常に素朴な方法でカーネルを起動しました。

const int tpb = 64; //threads per block
dim3 grid = (n +tpb-1)/tpb; // n - face count in array
dim3 block = tpb;
//.. some memory allocation etc.
theKernel<<<grid,block>>>(dev_ptr, n);

カーネル内にループがありました:

__global__ void theKernel(Face* faces, int faceCount) {
    int offset = threadIdx.x + blockIdx.x*blockDim.x;
    if(offset >= faceCount)
        return;
    Face f = faces[offset];
    //..some initialization
    int RAY = -1;
    for(float alpha=0.0f; alpha<=PI; alpha+= alpha_step ){ 
        for(float beta=0.0f; beta<=PI; beta+= beta_step ){ 
            RAY++;
            //..calculation per ray in (alpha,beta) direction ...
            faces[offset].intersects[RAY] = ...; //some assignment

これはそれについてです。すべての方向をループして、faces配列を更新しました。私は正しく動作しましたが、CPUコードよりも速くなることはほとんどありませんでした。

そこで今日、私はコードを最適化して、はるかに多くのスレッドでカーネルを起動しようとしました。面ごとに1つのスレッドを使用する代わりに、面の光線ごとに1つのスレッドが必要です(つまり、1つの面に対して625のスレッドが機能します)。変更は簡単でした:

dim3 grid = (n*RAYS +tpb-1)/tpb;  //before launching . RAYS = 625, n = face count

とカーネル自体:

__global__ void theKernel(Face *faces, int faceCount){

int threadNum = threadIdx.x + blockIdx.x*blockDim.x;

int offset = threadNum/RAYS; //RAYS is a global #define
int rayNum = threadNum - offset*RAYS;

if(offset >= faceCount || rayNum != 0)
    return;

Face f = faces[offset];
//initialization and the rest.. again ..

そして、このコードはまったく機能しません。なんで?理論的には、(面ごとに625の)最初のスレッドのみが機能するはずですが、なぜこれが悪い(ほとんどない)計算になるのでしょうか?

よろしくお願いいたします。e。

4

2 に答える 2

0

任意の次元でのグリッドの最大サイズは65535です(CUDAプログラミングガイド、付録F)。変更前のグリッドサイズが1000だった場合は、625000に増やしました。これは制限よりも大きいため、カーネルは正しく実行されません。

グリッドサイズを次のように定義する場合

dim3 grid((n + tpb - 1) / tpb, RAYS);

その場合、すべてのグリッドの寸法は制限よりも小さくなります。blockIdxまた、カーネルでの使用方法を変更する必要があります。

于 2011-12-01T22:15:35.687 に答える
0

Heatsinkが指摘したように、おそらく利用可能なリソースを超えています。カーネルの実行後にエラーがなかったかどうかを確認することをお勧めします。

これが私が使用するC++コードです:

#include <cutil_inline.h>

void
check_error(const char* str, cudaError_t err_code) {
    if (err_code != ::cudaSuccess)
        std::cerr << str << " -- " << cudaGetErrorString(err_code) << "\n";
}

次に、カーネルを無効にすると、次のようになります。

my_kernel <<<block_grid, thread_grid >>>(args);
check_error("my_kernel", cudaGetLastError());
于 2011-12-01T22:26:33.517 に答える