我编写了一个代码,用于将2个长度为“N”的元素相乘,并在CUDA 5.0中返回相同长度的乘积向量。这是我的代码 我改变了“N”的值,只看到GPU与CPU的比较。我能够达到200万个元素。但是当我去3000000000时,我收到了警告:
vecmul.cu(52): warning: floating-point value does not fit in required integral type
vecmul.cu(52): warning: floating-point value does not fit in required integral type
vecmul.cu: In function `_Z6vecmulPiS_S_':
vecmul.cu:15: warning: comparison is always false due to limited range of data type
vecmul.cu: In function `int main()':
vecmul.cu:40: warning: comparison is always true due to limited range of data type
这是我的代码
// Summing 2 Arrays
#include<stdio.h>
#include <fstream>
#define N (3000000000)
//const int threadsPerBlock = 256;
// Declare add function for Device
__global__ void vecmul(int *a,int *b,int *c)
{
int tid = threadIdx.x + blockIdx.x * blockDim.x;
if (tid >= N) {return;} // (LINE 15)
c[tid] = a[tid] * b[tid];
}
int main(void)
{
// Allocate Memory on Host
int *a_h = new int[N];
int *b_h = new int[N];
int *c_h = new int[N];
// Allocate Memory on GPU
int *a_d;
int *b_d;
int *c_d;
cudaMalloc((void**)&a_d,N*sizeof(int));
cudaMalloc((void**)&b_d,N*sizeof(int));
cudaMalloc((void**)&c_d,N*sizeof(int));
//Initialize Host Array
for (int i=0;i<N;i++) // (LINE 40)
{
a_h[i] = i;
b_h[i] = (i+1);
}
// Copy Data from Host to Device
cudaMemcpy(a_d,a_h,N*sizeof(int),cudaMemcpyHostToDevice);
cudaMemcpy(b_d,b_h,N*sizeof(int),cudaMemcpyHostToDevice);
// Run Kernel
int blocks = int(N - 0.5)/256 + 1; // (LINE 52)
vecmul<<<blocks,256>>>(a_d,b_d,c_d);
// Copy Data from Device to Host
cudaMemcpy(c_h,c_d,N*sizeof(int),cudaMemcpyDeviceToHost);
// Free Device Memory
cudaFree(a_d);
cudaFree(b_d);
cudaFree(c_d);
// Free Memory from Host
free(a_h);
free(b_h);
free(c_h);
return 0;
}
这是因为块的数量不足以满足此数组的大小吗? 任何建议都会受到欢迎,因为我是CUDA的初学者。 我在NVIDIA Quadro 2000上运行它。
答案 0 :(得分:2)
错误是由溢出32位signed int引起的。 2147483648是最大32位signed int,因此N将始终为负,导致布尔测试始终返回警告所指定的true / false。
另一个问题是
int blocks = int(N - 0.5)/256 + 1; // (LINE 52)
尝试将N转换为浮点然后将其转换为int。浮点数中的值太大 - 再次因为您溢出了32位int。
我认为如果你可以删除int(),它会起作用,因为一旦你除以256,你就会足够小,但你在分割之前强制它为int,所以它太大会导致错误。这不是分配到块中的问题,而是显式转换为int。
编辑:想知道我们是否已经修复了N和浮点vs int的一些计算问题,你会发现溢出问题。例如:
for (int i=0;i<N;i++) // (LINE 40)
{
a_h[i] = i;
b_h[i] = (i+1);
}
当N超过2 ^ 31-1时,这将始终为真(至少直到i溢出。这应该导致这是一个无限循环或者可能做2 ^ 31-1次迭代然后退出?编译器说它总是真的,如果是这样的话,循环应该永远不会结束。
另外,我不知道CUDA中的size_t是什么,但是
cudaMemcpy(c_h,c_d,N*sizeof(int),cudaMemcpyDeviceToHost);
当N = 3B时,做N * sizeof(int)的时间超过2 ^ 31甚至2 ^ 32。
在某些时候,您需要问问自己为什么要分配这么多空间以及是否有更好的方法。