私は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。