如何正确存储要与parfor一起使用的变量?

问题描述 投票:1回答:1

我的计算基于一棵二叉树,该树采用一个变量块的两个先前实例(称为程序集),并生成另一个。基于上分支的两个程序集生成一个新程序集,因此必须存储所有变量。

为此,我使用具有以下语法的单元格数组:Assembly_ij = Tree{ithBranch}{jthAssembly},其中Assembly18x3 double矩阵。这种方法是Matlab的allowed,但是,它根本没有改善代码的执行。我认为这是由于我不恰当地将变量传递给工人的原因。我收到以下警告:

整个数组或结构'Tree'是一个广播变量。这个可能会导致不必要的通信开销。

[大部分工作已在此部分代码中完成,它应该传达我正在犯的错误。

initialBranch = initialize();
Tree{1} = initialBranch;
for i = 2 : Nbranches
    branch = cell(1, elmsInBranch(i));
    parfor j = 1 : elmsInBranch(i)
        branch{j} = assembleBlocks(Tree{i-1}{2*j-1}, Tree{i-1}{2*j});
    end
    Tree{i} = branch;
end 

Matlab必须确保将整个Tree结构传递给每个工作人员,这是很多无用的复制。我不知道如何重写它以使其正常工作,但是,也许[[有某种聪明的方法可以只提取每个工人所需的变量?

matlab parallel-processing
1个回答
0
投票
问题是,您要将整个Tree{i-1}变量传递到parfor循环的每个(并行)迭代中。这是因为MATLAB解释器不够“灵巧”,无法确定您需要Tree{i-1}的哪些部分,因为您需要根据j进行一些计算来动态索引它。

分配一个可以在外循环中直接用j索引的临时变量,应解决此问题:

initialBranch = initialize(); Tree{1} = initialBranch; for i = 2 : Nbranches N = elmsInBranch(i); branch = cell(1, N); iTrees = cellfun( @(j) Tree{i-1}([2*j-1,2*j]), 1:N, 'uni', 0 ); parfor j = 1 : N jTrees = iTrees{j}; branch{j} = assembleBlocks(jTrees{1}, jTrees{2}); end Tree{i} = branch; end

请注意,我添加的cellfun对您的数据进行了分区,以便每个并行节点可以一次直接索引一个元素,其中包含循环中所需的两个Tree项。这可能会导致内存中的重复,但是与向每个节点广播整个阵列相比,重复的次数要少!
© www.soinside.com 2019 - 2024. All rights reserved.