我理解为什么结果是无穷大的。我写下面的代码,我总是收到inf作为结果。我的代码有任何精度问题吗?
#include <stdio.h>
#include <stdlib.h>
#include "cuda.h"
#include "curand_kernel.h"
#define NDIM 30
#define NPAR 5
#define DIMPAR NDIM*NPAR
__device__ double uniform(int index){
return (double) 0.767341;
}
__global__ void iteracao(double *pos){
int thread = threadIdx.x + blockDim.x * blockIdx.x;
double tvel;
int i = 0;
double l, r, t;
if(thread < DIMPAR){
do{
t = (double) uniform(thread);
l = (double) 2.05 * t * ( pos[thread] );
r = (double) 2.05 * t * ( pos[thread] );
tvel = (double) l+t+r;
pos[thread] = tvel;
i++;
}while(i < 10000);
}
}
int main(int argc, char *argv[])
{
double *d_pos, *h_pos;
h_pos = (double *) malloc(sizeof( double ) * DIMPAR);
cudaMalloc((void**)&d_pos, DIMPAR * sizeof( double ));
int i, j, k, numthreadsperblock, numblocks;
numthreadsperblock = 512;
numblocks = (DIMPAR / numthreadsperblock) + ((DIMPAR % numthreadsperblock)?1:0);
//
printf("numthreadsperblock: %i;; numblocks:%i\n", numthreadsperblock, numblocks);
cudaMemset(d_pos, 0.767341, DIMPAR * sizeof( double ));
iteracao<<<numblocks,numthreadsperblock>>>(d_pos);
cudaMemcpy(h_pos, d_pos, DIMPAR * sizeof( double ), cudaMemcpyDeviceToHost);
printf("\n");
for(i = 0; i < NPAR; i++){
for(j = i*NDIM, k = j; j < (k+30); j++){
printf("%f,", h_pos[j]);
}
printf("***\n\n");
}
system("PAUSE");
return 0;
}
输出始终如下:
numthreadsperblock:512 ;; numblocks:1
INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF ,INF,INF,INF,INF,INF,INF, * 的
INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF ,INF,INF,INF,INF,INF,INF, * 的
INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF ,INF,INF,INF,INF,INF,INF, * 的
INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF ,INF,INF,INF,INF,INF,INF, * 的
INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF ,INF,INF,INF,INF,INF,INF, * 的
答案 0 :(得分:2)
你有两个问题。第一个是@Anycorn在评论中所描述的。 cudaMemset
,就像memset
期望一个字节值并设置字节位置一样。您无法使用它来初始化float
值。
第二个是你的内核有一个在每个pos
数组元素上运行10000次的循环。实际上,您正在查找复杂表达式的10000因子。由于这种表达总是积极的,你的答案就会爆发。很可能你的内核写得不正确。它没有做你想做的事。即使您修复了第一个问题并将pos
正确初始化为零,您的计算仍然会爆炸。
您正在执行的算法是:
pos[idx] = 0.767341 + (3.1460981 * pos[idx]);
对于每个idx
,您执行上述操作10000次。即使初始pos[idx]
值等于零,在循环的第二次迭代中,它也将开始以几何方式起飞。
答案 1 :(得分:1)
你以错误的方式初步d_pos
。 cudaMemset()
只能逐字节设置内存。见cudaMemset() doc
了解更多详情。
要按预期启动数组,可以使用Thrust作为快速方式。
thrust::fill(
thrust::device_pointer_cast(d_pos),
thrust::device_pointer_cast(d_pos) + DIMPAR,
0.767341);