580
社区成员
发帖
与我相关
我的任务
分享
for (i=0; i<n; i++)
{
s = (y[i+1]-y[i])/m;
for(j=1; j<= m; j++)
{
x[m*i+j] = (y[i]+j*s);
}
}
__global__ void loop(double *x, double *y, double *s, int n, int m)
{
int tid = threadIdx.x + blockDim.x * blockIdx.x;
while(tid <m*n)
x[tid] = y[blockIdx.x] + s[blockIdx.x] * threadIdx.x;
}
__global__ void loop(double *x, double *y, double *s, int n, int m)
{
int tid = (threadIdx.x + 1) + blockDim.x * blockIdx.x;
for (int i=0; i<n; i++ )
{
while (tid<=m)
{
x[m*i+tid] = y[i] + s[i] * tid;
tid += blockDim.x*gridDim.x;
}
}
}
// 启动核函数
dim3 nblocks(48,1,1);
dim3 nthreadsperblock(128,1,1);
loop<<<nblocks , nthreadsperblock>>>(dev_x,dev_y,dev_s,n,m);
关于一个线程计算n次这部分代码,我心里还有疑惑,不知道这样实现是否正确?[/quote]
楼主 的意思可否理解成如下?通过48*128个线程,每个线程做28858/(48*128)个点的计算?
这种方法本身是没有问题的,但是代码部分却是可以斟酌的
实际上,楼主的写法仍然是双重循环,这种写法的效率是相当低的。
可以直接写成如下形式:
for(int i=0;i<m;i+=blockDim.x*gridDim.x)
x[m*i+tid] = y[i] + s[i] * tid;
这和楼主的代码处理结果实际是等效的,但是在运算效率上却会提高很多
另外,有几个问题建议楼主注意:
1.需要处理的次数m=28858并不是线程个数P=48*128的整数倍,因此需要对部分数据做额外处理,这里有2种方法
一种是if(tid<m)的形式,通过对线程id来判断
另一种是数据补零的方式,在m后面补若干个0,保证每个线程处理的个数均是相同的,即每个线程处理(m+P-1)/P个点的数据
2.楼主的代码中用到了x=y+n*tid形式的数据,不建议楼主才用这种形式,如果是在share memory中,会造成严重的bank conflict
此外,楼主的代码创建核函数时并不需要使用3维网格形式,2维足以__global__ void loop(double *x, double *y, double *s, int n, int m)
{
int tid = (threadIdx.x + 1) + blockDim.x * blockIdx.x;
for (int i=0; i<n; i++ )
{
while (tid<=m)
{
x[m*i+tid] = y[i] + s[i] * tid;
tid += blockDim.x*gridDim.x;
}
}
}
// 启动核函数
dim3 nblocks(48,1,1);
dim3 nthreadsperblock(128,1,1);
loop<<<nblocks , nthreadsperblock>>>(dev_x,dev_y,dev_s,n,m);
关于一个线程计算n次这部分代码,我心里还有疑惑,不知道这样实现是否正确?