【发布时间】:2014-04-06 12:54:30
【问题描述】:
对不起我的英语。我有一个 cuda 内核,它不时返回不同的结果值。该内核计算系列和。我的内核由 4 个代码部分组成。让我解释一下这个内核是如何工作的。第一部分在线程之间分配迭代(I took it as source)。第二个代码部分显示了每个线程如何计算半数。在第二部分之后我们必须放置 __syncthreads() 因为在第二部分之后我们开始使用共享内存。在第三部分中,我得到块中所有线程的总和,并将其放入 threadIdx.x 等于 0(I took it as source @ page 22) 的线程。在第四部分中,我得到所有线程块的总和并将其放入 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];
}
【问题讨论】:
-
你在做proper cuda error checking吗?当您使用
cuda-memcheck运行代码时会发生什么?你在什么类型的 GPU 上运行,你的nvcc编译命令行是什么?
标签: cuda