Erlang-并行梯度积分法

这个代码写了两天,从没思路到有思路,还好最终搞定了~不过这个进程数必须为2^n个。
先贴一个运行截图:
这里写图片描述

-module(exe4).
-export([start/5]).

start(F,X1,X2,Num,Cores)
    ->spawn(fun()->parent_proces(F,X1,X2,Num,Cores) end),
    io:format("").

parent_proces(F,X1,X2,Num,Cores) 
    ->creat_child_proces(F,X1,X2,(X2-X1)/Num,erlang:trunc(Num/Cores),Cores,Num,Cores,[]).

creat_child_proces(F,X1,X2,Width,Num_Per_Core,Cores,Num,N,L) 
      when N =:=1 -> 
      Pid = spawn(fun()->child_proces(F,X1,Width,Num-(Cores-1)*Num_Per_Core,0,N) end),
      Father = self(),
      PidR = spawn(fun()->loop_control(Father,0,Cores,2) end),
      sendInfo(L++[Pid]++[PidR],1,Cores,2,Cores);
creat_child_proces(F,X1,X2,Width,Num_Per_Core,Cores,Num,N,L)
      ->Pid=spawn(fun()->child_proces(F,X1,Width,Num_Per_Core,0,N) end),
        creat_child_proces(F,X1+Width*Num_Per_Core,X2,Width,Num_Per_Core,Cores,Num,N-1,L++[Pid]).

%子进程求部分和
child_proces(F,X1,Width,0,Sum,N1) -> io:format("~p 's result is ~p~n",[self(),Sum]),
                                     loop_send_get(Sum);
child_proces(F,X1,Width,N,Sum,N1) -> S=(F(X1)+F(X1+Width))*Width/2,
                                    child_proces(F,X1+Width,Width,N-1,Sum+S,N1).
%子进程部分和的发送和接收,由主进程sendInfo方法控制
loop_send_get(Sum) ->
        receive 
                {From,Sum1,Father,PidR} ->
                        io:format("~p from ~p to ~p result is ~p ~n",[Sum1,From,self(),Sum1+Sum]),
                        PidR!{"ok"},
                        loop_send_get(Sum+Sum1);
                {Pid,Father,PidR} ->
                        Pid!{self(),Sum,Father,PidR}
        end.
%控制每一轮迭代求和的次数,N为一轮迭代中求和的次数,初始值为0,Divisor为控制变量,初始值为2
loop_control(Father,N,Cores,Divisor) ->%io:format("N:~p Divisor:~p~n",[N,Divisor]),
        if
            Cores =:= N*Divisor ->
                                Father!{self(),"over"},
                                loop_control(Father,0,Cores,Divisor*2);
            true ->
                    receive
                        {"ok"} ->   loop_control(Father,N+1,Cores,Divisor)
                    end

        end.
sendInfo(PidList,N,Cores,Divisor,Dsum) ->%io:format("Pidlist:~p ~nN:~p Cores:~p Divisor:~p Dsum:~p ~n",[PidList,N,Cores,Divisor,Dsum]),
                                        Nt = erlang:trunc(N),
            if
                Divisor =:= 2*Dsum -> io:format("over~n");

                Nt > Cores ->
                        receive
                            {From,"over"} ->sendInfo(PidList,1,Cores-Divisor/2,Divisor*2,Dsum)
                        end;
                Nt rem Divisor =:= 1 ->
                        sendInfo(PidList,N+Divisor/2,Cores,Divisor,Dsum);
                Nt rem Divisor =/= 1 ->
                        Pid_send = lists:nth(Nt,PidList),
                        Pid_get = lists:nth(erlang:trunc(Nt-Divisor/2),PidList),%io:format("send:~p get:~p~n",[Pid_send,Pid_get]),
                        Pid_send!{Pid_get,self(),lists:nth(erlang:trunc(Dsum+1),PidList)},
                        sendInfo(PidList,N+Divisor/2,Cores,Divisor,Dsum)         
            end.












  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值