无穷大导致双重操作 [英] infinity as result in double operation

查看:116
本文介绍了无穷大导致双重操作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我会理解为什么结果是无限的.我写下面的代码,我总是收到inf作为结果.我的代码有任何精度问题吗?

I would understand why the result is infinity. I write the code below and I always receive inf as result. There is any precision problem with my code?

#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

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, *

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,*

推荐答案

您有2个问题.第一个是@Anycorn在评论中描述的.与memset一样,cudaMemset需要一个字节值并设置字节位置.您不能使用它来初始化float值.

You have 2 problems. The first is as described by @Anycorn in the comments. cudaMemset, just like memset expects a byte value and sets byte locations. You cannot use it to initialize float values.

第二个是您的内核有一个循环,该循环在每个pos数组元素上运行10000次.实际上,您正在查找复杂表达式的10000阶乘.由于该表达式始终是肯定的,因此您的答案会很夸张.很可能您的内核编写不正确.它没有按照您想要的去做.即使您解决了第一个问题并将pos正确初始化为零,您的计算仍会爆炸.

The second is that your kernel has a loop that is operating 10000 times on each pos array element. In effect you are finding the 10000 factorial of a complicated expression. Since that expression is always positive, your answer blows up. In all probability your kernel is not written correctly. It is not doing what you want it to do. Even if you fix your first problem and properly initialize pos to zero, your calculation will still blow up.

您正在执行的算法是:

pos[idx] =  0.767341 + (3.1460981 * pos[idx]);

对于每个idx,您将执行10000次以上操作.即使对于初始pos[idx]值等于零,在循环的第二次迭代中,它也会开始以几何方式起飞.

For each idx, you are performing the above operation 10000 times. Even for an initial pos[idx] value equal to zero, by the 2nd iteration of your loop, it will start to take off geometrically.

这篇关于无穷大导致双重操作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆