【问题标题】:How to replace a loop-for of convolutions with arrayfun?如何用arrayfun替换卷积循环?
【发布时间】:2014-01-22 23:54:52
【问题描述】:

我在 MATLAB 中有一个 3d 矩阵卷积的 for 循环,我想将其替换为 arrayfun 所以它将在 GPU 上并行运行。

我也觉得有一种方法可以完全摆脱循环,但不确定如何:)

这是我的代码,有什么建议吗?谢谢。

for i=1:size(obj.W, 3)
   d(:, :, :, i) = convn(prev_delta(:, :, :, i), ...
       flipped_W(:, :, i), 'full');
end

【问题讨论】:

  • 如果目的是使用GPU来完成这个任务,也许你可以更直接地实现它parfor:cac.cornell.edu/matlab/TechDocs/Examples/BestPracticesGPU.aspx
  • parfor 跨 CPU 内核而不是 GPU 并行化 for 循环...无论如何,我使用 parfor 对其进行了测试,但没有得到任何性能提升(我的 CPU 上有 4 个内核)。
  • arrayfun(和gpuArray/arrayfun)将函数应用于数组的每个元素。您只是迭代一维并将convn 应用于整个数组。除非您想自己实现convn,否则我不确定arrayfun 是否适用。另外,我不知道,但gpuArray/convn 本身可能已经并行化了。
  • @horchler convn 可能是并行化的,但 for 循环不是,看起来很浪费..

标签: matlab gpgpu


【解决方案1】:

将输入数组转换为结构数组并应用arrayfun会有帮助吗?

我没有测试代码,你可以试试。

c = cell(size(obj.W, 3), 2);
p = prev_delta;
cell_p = squeeze(mat2cell(size(p,1),size(p,2),size(p,3),ones(1,size(p,4))));
w = flipped_W;
cell_w = squeeze(mat2cell(size(w,1), size(w,2),ones(1,size(w,3))));

c(:,1) = cell_p;
c(:,2) = cell_w;

names = {'p','w'};

s = cell2struct(c, names, 2);

d = arrayfun(@(x)(covn(x.p, x.w, 'full'), s);

你应该注意 d 的返回值。

【讨论】:

  • 您的代码在经过几次修复后确实可以工作,但它比 for 循环慢 3 倍左右。
  • @Ran:... 是的,这只是打电话给arrayfun 的一种方式。对不起,我不熟悉GPU。正如@horchler 所说,您必须使用gpuArray 将数据发送到GPU。但不幸的是,gpuArray 仅支持原生数组和标量,因此无法将 s 发送到 GPU。也许你必须编写 CUDA 代码。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-04
  • 1970-01-01
  • 2018-11-24
  • 2013-01-23
  • 2021-06-01
  • 2018-06-29
相关资源
最近更新 更多