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.












發佈了45 篇原創文章 · 獲贊 8 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章