2014-02-24 60 views
0

通信开销(PARFOR)和预分配的速度,多维数组(对于)优化多维数组性能 - MATLAB

我在用**的

    指示的地方,下面的脚本让两个警告
  1. 变量被索引但没有切片...(在第二个parfor循环中由**显示的数组A) - 是什么导致了这种情况以及如何避免这种情况?

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

编辑:我最初的想法是预先分配的阵列(如在第一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); 
+0

您是如何预先分配内存的? – bdecaf

+0

@bdecaf我刚刚意识到我在第一个parfor循环中做了什么(我的预分配思路)是完全错误的!什么是预先分配多维数组的最佳方式? – user2550888

+0

基本上,我做'NaN(3,4,5,...)',只需在其中按顺序写入尺寸的大小(你可以用'零'或'ones'来做同样的事情,但我更喜欢看什么时候一个值尚未分配)。 – bdecaf

回答

0

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

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理解为切片

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

最后一个语法A,我认为你可以这样做,因为像这样一个向量化串联:

Sol = [Sol1; Sol2]; 

编辑 在GPU上,你可以使用pagefun得到谁如下所示:

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

谢谢,几乎加快了45%! 我已经注意到它更快地完成整个矩阵乘法,而不是将其分成行1 x列和行2 x列,并按上述方法连接。 因此,有关优化脚本的以下部分的任何建议? 't2 = tic; (:,:i)= A(:,:,i)* X(:,:,i); 结束 toc(t2);' – user2550888

+0

另外,值得一提的是,我的最终目标是在GPU上运行此并行代码 – user2550888

+0

感谢,'pagefun'真的很有帮助,我得到了一个巨大的加速!是否可以使用其他GPU就绪函数而不是'@ mtimes'?例如。我想为'Ag(1,:,N)'计算'norm',可以使用'pagefun'完成吗? – user2550888