我正在尝试学习CUDA,以下代码适用于值N <= 16384,但是对于更大的值失败(代码末尾的求和检查失败,索引值的c值始终为0) of i> = 16384)。
#include<iostream>
#include"cuda_runtime.h"
#include"../cuda_be/book.h"
#define N (16384)
__global__ void add(int *a,int *b,int *c)
{
int tid = threadIdx.x + blockIdx.x * blockDim.x;
if(tid<N)
{
c[tid] = a[tid] + b[tid];
tid += blockDim.x * gridDim.x;
}
}
int main()
{
int a[N],b[N],c[N];
int *dev_a,*dev_b,*dev_c;
//allocate mem on gpu
HANDLE_ERROR(cudaMalloc((void**)&dev_a,N*sizeof(int)));
HANDLE_ERROR(cudaMalloc((void**)&dev_b,N*sizeof(int)));
HANDLE_ERROR(cudaMalloc((void**)&dev_c,N*sizeof(int)));
for(int i=0;i<N;i++)
{
a[i] = -i;
b[i] = i*i;
}
HANDLE_ERROR(cudaMemcpy(dev_a,a,N*sizeof(int),cudaMemcpyHostToDevice));
HANDLE_ERROR(cudaMemcpy(dev_b,b,N*sizeof(int),cudaMemcpyHostToDevice));
system("PAUSE");
add<<<128,128>>>(dev_a,dev_b,dev_c);
//copy the array 'c' back from the gpu to the cpu
HANDLE_ERROR( cudaMemcpy(c,dev_c,N*sizeof(int),cudaMemcpyDeviceToHost));
system("PAUSE");
bool success = true;
for(int i=0;i<N;i++)
{
if((a[i] + b[i]) != c[i])
{
printf("Error in %d: %d + %d != %d\n",i,a[i],b[i],c[i]);
system("PAUSE");
success = false;
}
}
if(success) printf("We did it!\n");
cudaFree(dev_a);
cudaFree(dev_b);
cudaFree(dev_c);
return 0;
}
我认为这是一个与共享内存相关的问题,但我无法提出一个很好的解释(可能缺乏知识)。你能给我一个解释和一个解决方法来运行N大于16384的值。这是我的GPU的规格:
General Info for device 0
Name: GeForce 9600M GT
Compute capability: 1.1
Clock rate: 1250000
Device copy overlap : Enabled
Kernel Execution timeout : Enabled
Mem info for device 0
Total global mem: 536870912
Total const mem: 65536
Max mem pitch: 2147483647
Texture Alignment 256
MP info about device 0
Multiproccessor count: 4
Shared mem per mp: 16384
Registers per mp: 8192
Threads in warp: 32
Max threads per block: 512
Max thread dimensions: (512,512,64)
Max grid dimensions: (65535,65535,1)
答案 0 :(得分:3)
您可能打算写
while(tid<N)
不
if(tid<N)
答案 1 :(得分:0)
您的共享内存不足,您的矢量数组正被复制到设备的全局内存中。正如您所看到的,它具有比您需要的196608字节(16384 * 4 * 3)更多的可用空间。
你的问题的原因是你每个线程只执行一次加法运算,因此使用这种结构,你的向量可以是的最大维度是tera指出的内核启动中的块*线程参数。通过纠正
if(tid<N)
到
while(tid<N)
在你的代码中,每个线程将在多个索引上执行它的添加,并且将考虑整个数组。
有关内存层次结构和内存可以存在的各种不同位置的更多信息,您应该阅读随CUDA工具包提供的CUDA_C_Programming_Guide.pdf的第2.3和5.3节。
希望有所帮助。
答案 2 :(得分:0)
如果N是:
#define N (33 * 1024) //value defined in Cuda by Examples
我在 Cuda by Example 中找到的代码相同,但N的值不同。我认为N的值不能为33 * 1024.我必须更改块的参数数和每个块的线程数。这是因为:
add<<<128,128>>>(dev_a,dev_b,dev_c); //16384 threads
(128 * 128)&lt; (33 * 1024)所以我们崩溃了。