使用GPU时,为什么Arrayfun比for-loop快得多?

时间:2012-04-14 04:34:18

标签: matlab gpu-programming

有人能说出为什么Arrayfun比GPU上的for循环要快得多吗? (不是在CPU上,实际上For循环在CPU上更快)

Arrayfun:

x = parallel.gpu.GPUArray(rand(512,512,64));
count = arrayfun(@(x) x^2, x);

等效的For循环:

for i=1:size(x,1)*size(x,2)*size(x,3)
  z(i)=x(i).^2;        
end

可能是因为For循环在GPU上不是多线程的吗? 感谢。

2 个答案:

答案 0 :(得分:3)

我不认为你的循环是等价的。您似乎正在使用 CPU实现对数组中的每个元素进行平方,但是对 arrayfun 执行某种计数。

无论如何,我认为您正在寻找的解释如下:

在GPU上运行时,您可以在功能上对代码进行分解 - 在这种情况下分解为每个阵列单元 - 并单独进行平方。这没关系,因为对于给定的i[cell_i]^2的值不依赖于其他单元格中的任何其他值。最有可能发生的是将数组get分解为 S 缓冲区,其中 S 是您的GPU具有的流处理单元的数量。然后,每个单元计算其缓冲区的每个单元中的数据的平方。结果将复制回原始数组,结果将返回计数。

现在不要担心,如果你正在计算看起来像* array_fun *实际上正在做的事情,那么类似的事情正在发生。该算法最有可能将数组分成相似的缓冲区,而不是将每个单元格平方,而是将这些值一起添加。您可以将第一步的结果视为一个较小的数组,可以将相同的过程应用于递归计算新的总和。

答案 1 :(得分:1)

根据这里的参考页面http://www.mathworks.co.uk/help/toolbox/distcomp/arrayfun.html,“传入用于评估的MATLAB函数是为GPU编译的,然后在GPU上执行”。在显式for循环版本中,每个操作都在GPU上单独执行,这会产生开销 - arrayfun版本是一个GPU内核调用。