【问题标题】:How to use SPMD for different input variables and save the output in order?如何对不同的输入变量使用 SPMD 并按顺序保存输出?
【发布时间】:2018-08-27 08:13:51
【问题描述】:

我正在使用模拟退火算法来优化我的问题,我必须为 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

【问题讨论】:

    标签: matlab parallel-processing spmd


    【解决方案1】:

    来自spmd上的文档:

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

    因此输出是由 4 个元素组成的复合体,因为您有 4 个 CPU 内核,所以 output{1} 为您提供第一个元素,output{2} 第二个等。只需将它们连接起来即可在单个矩阵中获得输出。

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

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

    【讨论】:

    • 谢谢你的回答,我已经知道瓶颈在哪里,就是你已经说过的地方,嵌套循环从 开始。将内循环改为对吗?
    猜你喜欢
    • 2019-07-26
    • 1970-01-01
    • 1970-01-01
    • 2020-05-30
    • 2016-08-16
    • 2021-06-02
    • 2023-02-14
    • 1970-01-01
    • 2018-01-18
    相关资源
    最近更新 更多