【问题标题】:Matlab Parallelism toolbox : stacking loops in parforMatlab Parallelism 工具箱:parfor 中的堆叠循环
【发布时间】:2011-10-29 05:36:04
【问题描述】:

我正在尝试使用 matlab 并行程序包中的 parfor 循环。 我和这个人有类似的问题:MATLAB parfor slicing issue?。输出矩阵似乎没有被识别为切片变量。在我的具体情况下,我试图在 parfor 中堆叠使用其他 for 循环,并且我无法将其他线程中提出的解决方案应用于我的问题。这是我正在尝试做的一个虚拟示例:

n=175;
matlabpool;

Matred=zeros(n,n);

Matx2Cell = cell(n);

parfor i=1:n
    for j=1:n
        for k=1:n

            Matred(j,k)=exp((j+i+k)/500)
        end;
    end;
    Matx2Cell{i}=Matred;

end;
matlabpool close;

附:我知道将 parfor 放在 k-loop 而不是 i-loop 上会起作用......但我仍然想把它放在 i-loop 上(我相信它在我的真实环境中会更省时程序)。

非常感谢 弗雷德里克·戈丁

【问题讨论】:

    标签: for-loop parallel-processing matlab


    【解决方案1】:

    您可以将Matred = zeros(n); 放入parfor 主体中,但这很慢。而是在其中定义一个带有Matred = zeros(n); 的函数:实际上是相同的,但要快得多:

    function Matred = calcMatred(i,n)
    Matred=zeros(n);
    for j=1:n
        for k=1:n
            Matred(j,k)=exp((j+i+k)/500);
        end
    end
    

    这是一个时间比较:

    matlabpool
    n = 175;
    Matx2Cell = cell(n,1);
    
    tic
    parfor i=1:n
        Matred=zeros(n);
        for j=1:n
            for k=1:n
                Matred(j,k)=exp((j+i+k)/500);
            end
        end
        Matx2Cell{i}=Matred;
    end
    toc
    
    tic
    parfor i=1:n
        Matx2Cell{i}=calcMatred(i,n);
    end
    toc
    
    matlabpool close
    

    在我的机器上,第一个需要 7 秒,第二个需要 0.3 秒。

    还请注意,我已将 Matx2Cell 的声明更改为 cell(n,1),因为 cell(n) 创建了一个 n x n 单元格数组。

    【讨论】:

    • 你有解释为什么在单独的函数中重构代码更快吗?
    • @Amro:简短的回答是我不知道。我认为这是因为 MATLAB 不必考虑 Matred 是循环、切片、广播、归约还是临时变量,因为它只在函数的工作区中。当我在准备答案时看到减速时,我想这样做;在过去,我发现最好通过调用函数使parfor 的内容变得非常简单,因为依赖关系很明显。在该功能中,您具有很大的灵活性,例如您可以调用脚本,因为该函数有自己的工作区。
    • +1 谢谢你,这很有意义。我想我希望在进行并行计算时参考列出这些技巧和推荐做法的 MATLAB 文档。
    • 确实很有趣。看到你的帖子后,我立即打电话给BS,直到我尝试过。简直不敢相信。我很想用 Mathworks 提出这个问题,因为这是我想完全理解的一个重要消息。
    • @Ramashalanka 我收到了 Mathworks 的回复。 “两个程序之间存在性能差异的原因是由于 MATLAB 即时编译器 (JIT) 分析示例代码的方式。在第二种情况下,JIT 使用函数预编译代码。因此,在执行期间编译只发生一次,并且代码在 'parfor' 的每次迭代中都重复使用。相反,第一种情况的代码片段由 Matlab 为 'parfor' 的每次迭代解释,这会导致执行速度变慢。”
    【解决方案2】:

    您需要将 Matred 移动到 parfor 循环体中。这需要完成,因为 parfor 的每次迭代都需要 Matred 的新副本。

    n=175;
    matlabpool;
    
    Matx2Cell = cell(n);
    
    parfor i=1:n
        Matred=zeros(n,n);
        for j=1:n
            for k=1:n
    
                Matred(j,k)=exp((j+i+k)/500)
            end;
        end;
        Matx2Cell{i}=Matred;
    
    end;
    matlabpool close;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-06-10
      • 2014-10-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多