c语言 - CUDA 警告 "floating-point value does not fit in required integral type" - 为什么?



我在CUDA 5.0中编写了一个代码,用于将两个长度为"N"的元素向量相乘,并返回相同长度的乘积向量。这是我的代码我改变了"N"的值,只是看看GPU与CPU相比表现如何。我最多可以有2000000000个元素。然而,当我进入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上运行的

这些错误是由溢出32位有符号整型引起的。2147483648是最大32位有符号整型,因此N将始终为负,导致布尔测试始终返回警告指定的true/false。

另一个问题在

int blocks = int(N - 0.5)/256 + 1;   // (LINE 52)

试图将N转换为浮点数,然后再将其转换回整型。浮点数中的值太大——同样是因为溢出了32位整型。

我认为如果你可以删除int(),它将工作,因为一旦你除以256,你将足够小,但你强迫它在除法之前int,所以它太大导致错误。问题不在于赋值到block,而在于显式地转换为int。

编辑:想知道如果现在我们已经修复了N和浮点与int的一些计算问题,你会看到溢出问题。例如:

for (int i=0;i<N;i++)   // (LINE 40)
{
    a_h[i] = i;
    b_h[i] = (i+1);
}  

当N大于2^31-1时,这将总是导致true(至少在i溢出之前)。这应该导致这是一个无限循环,或者可能做2^31-1迭代,然后退出?编译器说它将永远为真,如果是这种情况,循环应该永远不结束。

另外,我不知道CUDA中的size_t是什么,但是

cudaMemcpy(c_h,c_d,N*sizeof(int),cudaMemcpyDeviceToHost);

执行N*sizeof(int)将远远大于2^31,甚至当N=3B时大于2^32。

有时候你需要问问自己为什么要分配这么多空间,是否有更好的方法

相关内容

最新更新