Parallel processing openCL还原,并传递2d数组

Parallel processing openCL还原,并传递2d数组,parallel-processing,opencl,reduction,Parallel Processing,Opencl,Reduction,下面是我想转换为openCL的循环 for(n=0; n < LargeNumber; ++n) { for (n2=0; n2< SmallNumber; ++n2) { A[n]+=B[n2][n]; } Re+=A[n]; } 我对这类事情完全是个新手。首先,我知道我不能向openCL内核传递全局双指针

下面是我想转换为openCL的循环

for(n=0; n < LargeNumber; ++n) {    
    for (n2=0; n2< SmallNumber; ++n2) {
        A[n]+=B[n2][n];
    }                                                         
    Re+=A[n];       
}

我对这类事情完全是个新手。首先,我知道我不能向openCL内核传递全局双指针。如果可以,请在发布解决方案之前等待几天左右,我想自己解决这个问题,但如果您能帮我指出正确的方向,我将不胜感激。

关于传递双指针的问题:这种问题通常通过复制整个矩阵(或您正在处理的任何内容)来解决进入一个连续的内存块,如果这些块有不同的长度通过另一个数组,该数组包含各个行的偏移量(因此您的访问看起来像
B[index[ii]+i]

现在让我们把你的问题简化为
Re
:既然你没有提到你正在使用的是哪种设备,我就假设它是GPU。在这种情况下,我将避免在同一个内核中进行缩减,因为它会像你发布它的方式一样慢(你必须通过数千个线程序列化对
Re
的访问(以及对
A[I]
的访问)。 相反,我将编写want内核,它将所有
B[*][I]
相加为
A[I]
,并将
A
的缩减放在另一个内核中的
Re
中,分几个步骤完成,也就是说,您使用一个对
n
元素进行操作的缩减内核,并将它们缩减为类似
n/16
(或任何其他数字)。然后您迭代调用该内核,直到只剩下一个元素,这就是您的结果(我故意让这个描述含糊不清,因为您说您想弄清楚自己的想法)

作为旁注:您意识到原始代码并没有很好的内存访问模式?假设
B
相对较大(由于第二维度的原因,比
a
大得多)让内部循环在外部索引上迭代将产生大量缓存未命中。当移植到gpu时,情况更糟,因为gpu对一致性内存访问非常敏感

因此,这样重新排序可能会大大提高性能:

for (n2=0; n2< SmallNumber; ++n2)
  for(n=0; n < LargeNumber; ++n)    
    A[n]+=B[n2][n];
for(n=0; n < LargeNumber; ++n)                                                 
  Re+=A[n];       
for(n2=0;n2

如果你有一个擅长自动矢量化的编译器,这一点尤其正确,因为它可能能够对该构造进行矢量化,但它不太可能对原始代码进行矢量化(如果它不能证明
a
B[n2]
不能引用相同的内存,那么它就不能将原始代码转换成这个)

“我不能将全局双指针传递给openCL内核”您的用词让我感到困惑。您可以传递双指针(例如“u global double*a”)。您不能传递2D指针(例如“u global int**B”)。您考虑过将程序拆分为两个单独的内核(按顺序执行)吗,一个是内环,一个是外环?谢谢!这让我想了很多。
for (n2=0; n2< SmallNumber; ++n2)
  for(n=0; n < LargeNumber; ++n)    
    A[n]+=B[n2][n];
for(n=0; n < LargeNumber; ++n)                                                 
  Re+=A[n];