LinuxシステムとTeslaC2075マシンで動作しています。リダクションカーネルの修正バージョンであるカーネルを起動しています。私の目的は、大規模なデータセット(結果)の平均と段階的な平均バージョン(time_avg)を見つけることです。以下のコードを参照してください。
「result」と「time_avg」のサイズは同じで、「nsamps」と同じです。「time_avg」には、配列結果の連続した平均セットが含まれます。したがって、前半には2つの重複しないサンプルごとの平均が含まれ、その後の四半期には4つの重複しないサンプルごとの平均が含まれ、次の8分の1は8つのサンプルごとに含まれます。
__global__ void timeavg_mean(float *result, unsigned int *nsamps, float *time_avg, float *mean) {
__shared__ float temp[1024];
int ltid = threadIdx.x, gtid = blockIdx.x*blockDim.x + threadIdx.x, stride;
int start = 0, index;
unsigned int npts = *nsamps;
printf("here here\n");
// Store chunk of memory=2*blockDim.x (which is to be reduced) into shared memory
if ( (2*gtid) < npts ){
temp[2*ltid] = result[2*gtid];
temp[2*ltid+1] = result[2*gtid + 1];
}
for (stride=1; stride<blockDim.x; stride>>=1) {
__syncthreads();
if (ltid % (stride*2) == 0){
if ( (2*gtid) < npts ){
temp[2*ltid] += temp[2*ltid + stride];
index = (int)(start + gtid/stride);
time_avg[index] = (float)( temp[2*ltid]/(2.0*stride) );
}
}
start += npts/(2*stride);
}
__syncthreads();
if (ltid == 0)
{
atomicAdd(mean, temp[0]);
}
__syncthreads();
printf("%f\n", *mean);
}
起動構成は40ブロック、512スレッドです。データセットは約40kサンプルです。
私のメインコードではcudaGetLastError()
、カーネル呼び出しの後に呼び出しますが、エラーは返されません。メモリ割り当てとメモリコピーはエラーを返しません。カーネル呼び出しの後に書くcudaDeviceSynchronize()
(またはcudaMemcpy
平均値をチェックする)と、カーネル呼び出しの後でプログラムが完全にハングします。削除すると、プログラムが実行されて終了します。どちらの場合も、「ここに」出力または平均値が出力されますか。カーネルが正常に実行されない限り、printfは印刷されないことを理解しています。これは__syncthreads()
再帰と関係がありますか?すべてのスレッドが同じ深さまで進むので、チェックアウトすると思います。
ここでの問題は何ですか?
ありがとうございました!