我的计算基于一棵二叉树,该树采用一个变量块的两个先前实例(称为程序集),并生成另一个。基于上分支的两个程序集生成一个新程序集,因此必须存储所有变量。
为此,我使用具有以下语法的单元格数组:Assembly_ij = Tree{ithBranch}{jthAssembly}
,其中Assembly
是18x3 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结构传递给每个工作人员,这是很多无用的复制。我不知道如何重写它以使其正常工作,但是,也许[[有某种聪明的方法可以只提取每个工人所需的变量?
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
项。这可能会导致内存中的重复,但是与向每个节点广播整个阵列相比,重复的次数要少!