0

1 次元のブロックで使用すると正常に動作する次のコードがあります。

__global__ void dot_product_large_arrays( int N, double *a, double *b,
                     double *res)
{

  __shared__ double cache[TILE_DIM];
  int tid = threadIdx.x + blockIdx.x * blockDim.x;
  int i = 0, cacheIndex = 0;
  double temp = 0;
  cacheIndex = threadIdx.x;

  while (tid < N) {
    temp += a[tid] * b[tid];
    tid += blockDim.x*gridDim.x;
  }
  cache[cacheIndex] = temp;
  __syncthreads();

  for (i = blockDim.x/2; i > 0; i>>=1) {
    if (threadIdx.x < i) {
      cache[threadIdx.x] += cache[threadIdx.x + i];
    }
    __syncthreads();
  }
  __syncthreads();

  if (cacheIndex == 0) {
    atomicAdd(res, cache[0]);
  }
}

現在、私の配列のサイズ9000*9000は、計算に使用できるブロックの数に収まりません。Xブロックを使用して拡張することを考えたYので、私の変更は次のとおりです。

int tid = threadIdx.x + blockIdx.x * blockDim.x +
       blockDim.x*gridDim.x*blockIdx.y;
                  ...
while (tid < N) {
    temp += a[tid] * b[tid];
    tid += blockDim.x*gridDim.x*blockIdx.y*grimDim.y;
  }

そして私のカーネル呼び出し

int totalThreads = 9000*9000;
int blockSize = 512;
int blockDimY = 256;
int blockDimX = (totalThreads/( blockSize*blockDimY))+ 1;

dim3 dimGrid(blockDimX,blockDimY);
dim3 dimBlock(blockSize);

dot_product_large_arrays <<< dimGrid, dimBlock >>>(totalThreads, d_a, d_b, d_res);

それはコンパイルされ、実行されますが、決して終了しません(?!)、ここで私が間違っていることのアイデアはありますか?

4

1 に答える 1

3

以下のtidをインクリメントしている行が問題のようです:

 while (tid < N) {  
    temp += a[tid] * b[tid];  
    tid += blockDim.x * gridDim.x * blockIdx.y * grimDim.y; //blockIdx.y can be zero
 }

少なくとも 1 つのブロックのブロック y インデックスが 0 になります。これは、0 ずつインクリメントし、1 つ以上のスレッドが無限ループに陥ることを意味します。

于 2013-02-14T12:35:09.347 に答える