私はグローバルメモリをゼロにする単純なCUDAプログラムで遊んでいます。以下はデバイスコードと同様にホストコードです:CUDAアドレス範囲外
#include <stdio.h>
__global__ void kernel(float *data, int width) {
int x = blockDim.x * blockIdx.x + threadIdx.x;
int y = blockDim.y * blockIdx.y + threadIdx.y;
if (x > (width-1)) {
printf("x = %d\n", x);
printf("blockDim.x = %d\n", blockDim.x);
printf("blockIdx.x = %d\n", blockIdx.x);
printf("threadIdx.x = %d\n", threadIdx.x);
}
if (y > (width-1)) {
printf("y = %d\n", y);
printf("blockDim.y = %d\n", blockDim.y);
printf("blockIdx.y = %d\n", blockIdx.y);
printf("threadIdx.y = %d\n", threadIdx.y);
}
data[y * width + x] = 0.0;
}
int main(void) {
const int MATRIX_SIZE = 256;
float *data, *dataGPU;
int sizeOfMem;
int x = MATRIX_SIZE;
int y = MATRIX_SIZE;
cudaDeviceReset();
cudaDeviceSynchronize();
sizeOfMem = sizeof(float) * x * y;
data = (float *)malloc(sizeOfMem);
cudaMalloc((void **)&dataGPU, sizeOfMem);
cudaMemcpy(dataGPU, data, sizeOfMem, cudaMemcpyHostToDevice);
//int threads = 256;
//int blocks = ((x * y) + threads - 1)/threads;
dim3 threads(16, 16);
dim3 blocks(x/16, y/16);
kernel<<<blocks, threads>>>(dataGPU, MATRIX_SIZE);
cudaThreadSynchronize();
cudaMemcpy(data, dataGPU, sizeOfMem, cudaMemcpyDeviceToHost);
cudaFree(dataGPU);
free(data);
return 0;
}
私はCUDA-memcheckと私のコードを実行するときに境界エラーメッセージのうちのアドレスを受信し続けます。しかし、これは私が作成した行列の大きさが128以上の場合のみです。 128より小さい次元の場合、エラーはそれほど頻繁ではありません(エラーはほとんどありません)。カーネル機能にprintステートメントが含まれていることに気付くかもしれません。これらのステートメントは、エラーメッセージが表示されたときにのみ出力されます。なぜなら、xとyは決してwidth-1より大きいはずがないからです。この場合、255となります。以下は、私はCUDA-memcheckから受信したエラーメッセージです:
========= CUDA-MEMCHECK
========= Invalid __global__ write of size 4
========= at 0x00000298 in kernel(float*, int)
========= by thread (3,10,0) in block (15,1,0)
========= Address 0x2300da6bcc is out of bounds
========= Saved host backtrace up to driver entry point at kernel launch time
========= Host Frame:/usr/lib64/nvidia/libcuda.so.1 (cuLaunchKernel + 0x2c5) [0x472225]
========= Host Frame:./test_reg_memory [0x16c41]
========= Host Frame:./test_reg_memory [0x31453]
========= Host Frame:./test_reg_memory [0x276d]
========= Host Frame:./test_reg_memory [0x24f0]
========= Host Frame:/lib64/libc.so.6 (__libc_start_main + 0xf5) [0x21b15]
========= Host Frame:./test_reg_memory [0x25cd]
=========
y = 2074
blockDim.y = 16
blockIdx.y = 1
threadIdx.y = 10
この出力は、私は数学をすれば、
y = blockDim.y * blockIdx.y + threadIdx.y = 16 * 1 + 10 = 26 (not 2074)
私はCUDAを見ていくつかの時間を費やしているので、私には意味がありません。プログラミングフォーラム、そして何も助けに見えなかった。私が読み込んだスレッドが1つあり、レジスタのメモリが壊れている可能性があることを示しています。しかし、スレッドを開始したものは、別のGPUでこの問題を抱えています。スレッドは少し関係がありませんが、私はリンクをとにかく含めました。 I以下
NVCCのバージョンが含まれています。
nvcc: NVIDIA (R) Cuda compiler driver
Copyright (c) 2005-2015 NVIDIA Corporation
Built on Tue_Aug_11_14:27:32_CDT_2015
Cuda compilation tools, release 7.5, V7.5.17
また、ここで私が使用しているGPUがあります。
Device 0: "GeForce GT 640"
CUDA Driver Version/Runtime Version 8.0/7.5
CUDA Capability Major/Minor version number: 3.0
私が間違っている可能性があることをCUDA経験のある人なら誰でも知ることができますか?
投稿したコードは正しく動作し、cuda-memcheckでエラーが発生しません。本当にあなたが投稿したコードが、あなたがSOの質問からコピー・ペーストしてコンパイルして実行すると、cuda-memcheckエラーが出ることは確実ですか? – talonmies
cudaMallocは成功しますか? –
@RegisPortalez:cudaMallocが失敗した場合、cuda-memcheckはエラーを報告します。投稿された出力にそのようなエラーはありません。 – talonmies