【问题标题】:Optimising multidimensional array performance- MATLAB优化多维数组性能 - MATLAB
【发布时间】:2014-02-24 13:50:38
【问题描述】:

多维数组中的通信开销 (parfor) 和速度预分配 (for)

我在以下脚本中的 **'s 指示的位置收到两个警告

  1. 变量已编入索引但未切片...(第二个 parfor 循环中 ** 显示的数组 A)- 是什么原因造成的,如何避免?

  2. 变量似乎在每个循环中都会改变大小...(在 for 循环中由 ** 显示的数组 Sol)- 也许我做得不对,但预分配内存没有奏效。

编辑:我最初的想法是预先分配数组(就像在第一个 parfor 循环中所做的那样),以便它更快地执行脚本的其余部分(脚本的完整版本重复各种数组操作,类似于第二个 parfor 和 for 循环)。

有什么建议吗? :)

N = 1000;

parfor i=1:N
    A(:,:,i) = rand(2);
    X(:,:,i) = rand(2,1);
    Sol1(1,1,i) = zeros();
    Sol2(1,1,i) = zeros();
    Sol(2,1,i) = zeros();
end


t0 = tic;

parfor i=1:N
    Sol1(1,:,i) = A(1,:,i)*X(:,1,i);
    Sol2(1,:,i) = **A**(2,:,i)*X(:,1,i);
end

for i=1:N
    **Sol**(:,1,i) = [Sol1(1,:,i);Sol2(1,:,i)];
end

toc(t0);

【问题讨论】:

  • 你是如何预分配内存的?
  • @bdecaf 我刚刚意识到我在第一个 parfor 循环中所做的(我的预分配想法)是完全错误的!为多维数组预分配的最佳方法是什么?
  • 基本上我做NaN(3,4,5,...),只需按顺序在其中写下尺寸的大小(你可以对zerosones做同样的事情-但我更喜欢看看什么时候没有值已分配)。

标签: performance matlab multidimensional-array


【解决方案1】:

您的预分配不正确 - 您需要在一次调用中完成每个操作。

A = rand(2, 2, N);
X = rand(2, 1, N);
Sol1 = zeros(1, 1, N);
Sol2 = zeros(1, 1, N);
Sol = zeros(2, 1, N); % not really needed actually.

在您的 PARFOR 循环中,您可以通过使用 MATLAB 理解为切片的语法来避免“广播”A

parfor i = 1:N
    tmp = A(:, :, i);
    Sol1(1, :, i) = tmp(1,:) * X(:, 1, i);
    Sol2(1, :, i) = tmp(2,:) * X(:, 1, i);
end

最后,我认为您可以像这样将其作为矢量化连接来实现:

Sol = [Sol1; Sol2];

编辑 在 GPU 上,您可以使用 pagefun 在一次调用中完成整个工作,如下所示:

Ag = gpuArray.rand(2,2,N);
Xg = gpuArray.rand(2,1,N);
Sol = pagefun(@mtimes, Ag, Xg);

【讨论】:

  • 谢谢,速度几乎提高了 45%!我注意到一次性完成整个矩阵乘法更快,而不是将其分成第 1 行 x 列和第 2 行 x 列,然后像我上面所做的那样连接。因此,对于优化脚本的以下部分有什么建议吗? t2 = tic; parfor i=1:N Sol(:,:,i) = A(:,:,i)*X(:,:,i); end toc(t2);
  • 另外,值得一提的是,我的最终目标是在 GPU 上运行此并行代码
  • 谢谢,pagefun 真的很有帮助,我得到了巨大的加速!是否可以使用其他支持 GPU 的功能而不是 @mtimes?例如。我想计算Ag(1,:,N)norm,可以使用pagefun 来完成吗?
  • 请问:您对norm的哪个版本最感兴趣?
猜你喜欢
  • 2014-05-30
  • 1970-01-01
  • 1970-01-01
  • 2019-05-31
  • 2023-03-30
  • 1970-01-01
  • 1970-01-01
  • 2012-10-25
  • 2015-08-27
相关资源
最近更新 更多