有人能说出为什么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上不是多线程的吗? 感谢。
答案 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内核调用。