cuda计算的结果正在不断变化

时间:2014-03-04 19:34:51

标签: cuda

抱歉我的英文。我有一个cuda内核,它不时返回不同的结果值。该内核计算序列总和。我的内核由4个代码部分组成。让我解释一下这个内核是如何工作的。第一部分在线程(I took it as source)之间分配迭代。第二个代码部分显示了每个线程如何计算halfsum。在第二部分之后我们必须放置__syncthreads(),因为在第二部分之后我们开始使用共享内存。在第三部分中,我获取了块中所有线程的结果总和并将其放入threadIdx.x等于0 (I took it as source @ page 22)的线程中。在第四部分中,Im获得所有线程块的结果总和并将其放入dSum [0]

我是否正确放置了 __ syncthreads()?哪里出错?为什么在64个块和768个线程上它给出了错误的结果,在768个块和64个线程上它给出了正确的结果?

__global__ void sumSeries(double* dSum,int totalThreadNumber){  
    volatile  __shared__ double data[768];  
    int tid=threadIdx.x+blockIdx.x*blockDim.x;
    int myend;
    double var;
    //part_1 get tid's start iteration value and end iteration value.
    int mystart = (INT_MAX / totalThreadNumber) * tid;
    if (INT_MAX %  totalThreadNumber > tid)
    {
        mystart += tid;
        myend = mystart + (INT_MAX /  totalThreadNumber) + 1;
    }
    else
    {
        mystart += INT_MAX %  totalThreadNumber;
        myend = mystart + (INT_MAX /  totalThreadNumber);
    }
    //part_2 get halfsum
    data[threadIdx.x]=0;
    for (int i = mystart ; i < myend ; ++i){
            var=i;
            data[threadIdx.x] += (var*var+var+1)/(var*var*var+var*var+var+1);

    }   
    __syncthreads();

    //part_3 sum all results in every block
    for (int s=blockDim.x/2; s>32; s>>=1)
    {
        if (threadIdx.x < s)
            data[threadIdx.x] += data[threadIdx.x + s];
        __syncthreads();
    }
    if (threadIdx.x < 32)
    {
        data[threadIdx.x] += data[threadIdx.x + 32];
        data[threadIdx.x] += data[threadIdx.x + 16];
        data[threadIdx.x] += data[threadIdx.x + 8];
        data[threadIdx.x] += data[threadIdx.x + 4];
        data[threadIdx.x] += data[threadIdx.x + 2];
        data[threadIdx.x] += data[threadIdx.x + 1];
    }

    if (threadIdx.x==0)
    {
        dSum[blockIdx.x]=data[0];
    }
    __syncthreads();
    //part_4
    if (tid==0)
        for (int t=1;t<8;++t)
            dSum[0]=dSum[0]+dSum[t];
}

1 个答案:

答案 0 :(得分:3)

所以你的总和就是

系列
(n^2+n+1)/(n^3+n^2+n+1) = (n^3-1)/(n^4-1)

具有与谐波系列相同的收敛性

1/n

即没有,它非常非常缓慢地向无穷远方向发散。从1到N之和的值在log(N)和1-log(2)+ log(N + 1)之间。

对于求和的顺序,这些序列的任何有限求和的结果是非常明智的。向前求和从1到N并且减少会抑制所有项,其中1 == 1 + 1 / n,这对于浮点数来说相当小。从N到1向后汇总将首先累积小数并保留其累积贡献。

因此,根据部分和的到达顺序,特别是当包含1的总和时,总和将显示明显的差异。


这两个词在

中单调递减
f(x) = (x^2+x+1)/(x^3+x^2+x+1) = 0.5/(x+1)+0.5*(x+1)/(x^2+1)

该功能的反衍生物是

F(n) = 0.5*ln(x+1)+0.25*ln(x^2+1)+0.5*arctan(x)

这样

f(n+1) <= F(n+1)-F(n) <= f(n) <= F(n)-F(n-1)

将此结果总结为

F(N+1)-F(m) <= sum(n=m to N) f(n) <= F(N)-F(m-1)

对于这个,必须在所有三个术语中添加总和的初始部分。

所以设m = 1000 , compute S = sum(n = 0到999)f(n)`,然后

S+F(2^32  )-F(1000) = 23.459829390459243
S+F(2^32-1)-F( 999) = 23.460829890558995

是0到2 ^ 32-1之和的上限和下限,远离任何数值结果。