码迷,mamicode.com
首页 > 其他好文 > 详细

Erlang-并行梯度积分法

时间:2015-04-14 00:47:01      阅读:232      评论:0      收藏:0      [点我收藏+]

标签: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.












Erlang-并行梯度积分法

标签:erlang   并行计算   

原文地址:http://blog.csdn.net/li8630/article/details/45034291

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!