抱歉我的英文。我有一个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];
}
答案 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之和的上限和下限,远离任何数值结果。