2015-04-29 67 views
3

我是一个新的for openCL。如何从数组中获得总和数组

我知道如何总结一维数组。但我的问题是如何从openCL中的1 1D数组中获得一个sum数组。

int a[1000]; 
int b[1000]; 
....    //save data to a 
for(int i = 0 ;i < 1000; i ++){ 
    int sum = 0; 
     for(int j = 0 ;j < i; j ++){ 
     sum += a[j]; 
     } 
     b[i] = sum; 
    } 

任何建议是值得欢迎的。

+0

你可以看看ArrayFire中OpenCL sum函数的源代码,它是开源的,在这里:http://www.arrayfire.com/docs/group__reduce__func__sum.htm – arrayfire

+0

我想你说的是“前缀总和“或”扫描“。对不起,现在没有答案,但像“prefix sum opencl”这样的websearches会带来一些结果,也许这已经有所帮助了。 – Marco13

+0

您的代码是前缀总和。它相当于'for(int i = 0; i <1000; j ++){sum + = a [j]; b [i] =总和; }'。 –

回答

0

正如其他人所说 - 你想要做的是使用包含并行前缀和。如果你被允许使用OpenCL 2 they have a workgroup function for it - 他们应该从一开始就使用OpenCL 2,因为它的使用频率很高 - 所以现在我们让每个人都自己实现它,通常很难以这种或那种方式实现。

查看http://http.developer.nvidia.com/GPUGems3/gpugems3_ch39.html为典型的算法来教这个。

在你提到的数字上,使用多个计算单元意味着你将用一个计算单元来攻击它 - 所以只需重复两次左右的循环 - 在64-256处,你将得到总和很多元素的速度非常快。基于工作组函数来获得任意大小的通用缩减函数是读者的一个练习。

0

这是一个顺序问题。用另一种方式表示

b[1] = a[0] 
b[2] = b[1] + a[1] 
b[3] = b[2] + a[2] 
... 
b[1000] = b[9999] + a[999] 

因此,有多个线程不会帮助你。 这样做的最佳方式是使用单个CPU。而不是OpenCL/CUDA/OpenMP ...

这个问题是完全不同的减少,每个步骤可以分为2个小步骤,可以并行运行。

+0

我认为你的答案应该解决OPs代码。即使效率低下,他的代码也并不重要。他做了'O(n^2)'读取(实际上'(n-1)* n/2'读取)和'n'写入。而你的建议只做'读'。这显然更好,但并行并不是微不足道的(它可以通过两遍)。 –