我是库达的初学者,在这方面有一些困难
如果输入向量A和结果向量B的大小都是N,而Bi依赖于除Ai以外的所有A元素,那么我如何才能在串行for循环中多次调用内核呢?我想不出有什么办法能同时使外循环和内环平行。
编辑:拥有一个具有cc 2.0的设备
示例:
// a = some stuff
int i;
int j;
double result = 0;
for(i=0; i<1000; i++) {
double ai = a[i];
for(j=0; j<1000; j++) {
double aj = a[j];
if (i == j)
continue;
result += ai - aj;
}
}
我现在有一个:
//in host
int i;
for(i=0; i<1000; i++) {
kernelFunc <<<2, 500>>> (i, d_a)
}
有办法消除串行循环吗?
发布于 2014-01-03 01:07:07
像这样的东西应该管用,我想:
__global__ void my_diffs(const double *a, double *b, const length){
unsigned idx = threadIdx.x + blockDim.x*blockIdx.x;
if (idx < length){
double my_a = a[idx];
double result = 0.0;
for (int j=0; j<length; j++)
result += my_a - a[j];
b[idx] = result;
}
}
(用浏览器编写,未经测试)
可以通过几种方式对此进行进一步优化,但是对于具有L1缓存的cc 2.0和较新设备,这些优化的好处可能很小:
double
元素?)所以好处可能是有限的j
索引)。同样,对于cc 2.0和更新的设备,由于L1缓存以及广播扭曲全局读取的能力,这可能没有多大帮助。如果您必须使用cc 1.x设备,那么您将从一个或多个优化中获得显著的里程--在这种情况下,我在这里展示的代码运行速度会明显减慢。
请注意,我选择了不考虑特殊情况,即我们要从自身中减去a[i]
,因为这应该是大约为零,而且不应该干扰您的结果。如果你关心这件事,你可以很容易地解决这个问题。
如果增加块并减少每个块的线程,您还将获得更高的性能,可能如下所示:
my_diffs<<<8,128>>>(d_a, d_b, len);
原因是许多GPU有超过1或2个SMs。为了在这些GPU上使用如此小的数据集来最大化perf,我们希望在每个SM上至少启动一个块。在网格中有更多的块使得这更有可能发生。
如果要完全并行化计算,方法是创建一个2D矩阵(让我们称之为c.)在GPU内存中,平方维的大小等于矢量的长度。然后,我将创建一个2D线程网格,让每个线程执行减法(a[row] - a[col]
),并将其结果存储在c[row*len+col]
中。然后,我将启动第二个(1D)内核来对c
的列和(每个线程都有一个循环来和一列)来创建结果向量b
。但是,我不确定这是否会比我所描述的方法更快。这种“更完全并行化”的方法也不会像我讨论的那样容易进行优化。
https://stackoverflow.com/questions/20894370
复制相似问题