如何将SPMD用于不同的输入变量并按顺序保存输出?



我正在使用模拟退火算法来优化我的问题,我必须对 100 个不同的输入变量执行此操作,并按顺序保存所有变量的输出。 问题是我不知道如何在代码中实现spmd来进行并行计算,以便每个输入在一个 CPU 内核上运行,最终结果存储在包含 100 行的矩阵中。我试图把它放在第一个 for 循环之前,但它只返回一个由 4 个元素组成的复合,因为我的 CPU 有 4 个内核。 这是我的代码

spmd
for v=1:100
posmat=loading_param(Matrix,v);
nvar=size(posmat,2); 
popsize=50;
maxiter=20;
T0=1000;
Tf=1;
Tdamp=((T0-Tf)/maxiter);
nn=5;
T=T0;
%% initial population
tic
emp.var=[];
emp.fit=inf;
pop=repmat(emp,popsize,1);
for i=1:popsize
pop(i).var=randperm(nvar);
pop_double=pop(i).var;
posmat_new=tabdil(nvar,pop_double,posmat);
dis=cij(posmat_new);
pop(i).fit=fittness(dis);
end
[value,index]=min([pop.fit]);
gpop=pop(index);
%% algorithm main loop 
BEST=zeros(maxiter,1);
for iter=1:maxiter
for i=1:popsize
bnpop=emp;
for j=1:nn
npop=create_new_pop(pop(j),nvar,posmat);
if npop.fit<bnpop.fit
bnpop=npop;
end
end
if bnpop.fit<pop(i).fit
pop(i)=bnpop;
else
E=bnpop.fit-pop(i).fit;
pr=exp(-E/T);
if rand<pr
pop(i)=bnpop;
end
end
end
T=T-Tdamp;

[value,index]=min([pop.fit]);
if value<gpop.fit
gpop=pop(index);
BEST(iter)=gpop.fit;
disp([ 'iter= ' num2str(iter) 'BEST=' num2str(BEST(iter))])
end
end

%% algorithm results
disp([ ' Best solution=' num2str(gpop.var)])
disp([ ' Best fittness=' num2str(gpop.fit)])
disp([ ' Best time=' num2str(toc)])
bnpop_all(d,:)=bnpop.var;
d=d+1;
end %end of main for loop
end % end of spmd

来自spmd的文档:

spmd语句主体返回的值将转换为 MATLAB 客户端上的复合对象。复合对象包含对存储在远程 MATLAB 工作线程上的值的引用,可以使用单元数组索引检索这些值。只要 Composite 存在于客户端上并且并行池保持打开状态,工作线程上的实际数据在工作线程上仍然可用,以便后续执行spmd

因此,输出是包含 4 个元素的复合,因为您有 4 个 CPU 内核,因此output{1}为您提供第一个元素,output{2}第二个元素,依此类推。只需将它们连接起来即可在单个矩阵中获取输出。

此时,您的代码仅运行四次,每个工作线程一次完整的 100 次迭代for循环。解决此问题的一种更简单的方法是使用parfor而不是spmd,因为您可以保持循环不变。如果要使用spmd,首先将v切成四个部分(每个部分 25 个元素(,然后在每个工作线程上仅迭代这 25 个元素。

看到你的代码,有三个嵌套循环,我建议现在不要并行化,而是尝试分析你的代码,找出瓶颈在哪里,并尝试加快这些瓶颈。可能尝试矢量化嵌套循环已经会有很大改进。

最新更新