您的位置:首页 > 其它

Erlang实现的矩阵相乘C=A*B单线程与并行多线程性能对比

2014-04-16 21:12 483 查看
-module(new).

-export([]).

-compile(export_all).

%% ====================================================================

%% Internal functions

%% ====================================================================

%%测试入口

test() ->

A = generateMatrix(50,300),

B = generateMatrix(300,30),

{Time,Value} = timer:tc(new,matrixMultiply,[A,B]),

io:format("Single Thread:~p[ms]~n",[Time/1000]),

{Time1,Value1} = timer:tc(new,multiThread,[A,B]),

io:format("Multi Thread:~p[ms]~n",[Time1/1000]).

%% 随机产生M*N矩阵

generateMatrix(M,N) ->

row(M,N,[]).

row(M,N,Result) ->

case 0 =:= M of

true -> Result;

false -> row(M-1,N,Result++[column(N,[])])

end.

column(N,Result) ->

case 0 =:= N of

true -> Result;

false -> column(N-1,Result++[random:uniform(1000)])

end.

%% 单线程

matrixMultiply(A,B) ->

R = lists:foldl(fun(Element,Acc) -> Acc++[rowMultiplyColumn(Element,B,[],1)] end, [], A),

io:format("~w~n",[R]).

%% 多线程

multiThread(A,B) ->

P = self(),

%% 启动矩阵A的行数个进程,分别发送A的每一行,计算A的每一行与矩阵B的乘积

lists:foldl(fun(Element,Acc) -> spawn(fun() -> P! {self(),Acc,rowMultiplyColumn(Element,B,[],1)} end) end, 1, A),

%% 接收,当前进程如果收到了A行数个消息,表明已经计算完毕

loop(length(A)).

%% 统计当前进程是否已经收到了Count条消息

loop(Count) ->

receive

{Pid,N,Result} ->

%% io:format("Count=~p,Message=~w~n",[Count,{Pid,N,Result}]),

case 1=:= Count of

true -> io:format("Compute end~n");

false -> loop(Count-1)

end

end.

%%@author zcc

%%@date 2014-04-16

%%@param A,B:list;Result:存放结果,初始为[];Count:控制列数,初始为1;Result:存放结果,初始为[]

%%将某一行A与矩阵B相乘,得出一组向量

rowMultiplyColumn(A,B,Result,Count) ->

case Count =:= length(lists:nth(1,B))+1 of

true -> Result;

false ->

rowMultiplyColumn(A,B,Result ++ [multiply(A,getMatrixColumn(B,Count),0)],Count+1)

end.

%% 得到矩阵B的第Num列

getMatrixColumn(B,Num) ->

lists:foldl(fun(A,Acc) -> Acc++[lists:nth(Num, A)] end, [],B).

%% 计算两个向量List的数量积

multiply([H1|T1],[H2|T2],Sum) when length(T1) =:= length(T2) ->

multiply(T1,T2,Sum+H1*H2);

multiply([],[],Sum) -> Sum.

%% 计算两个向量积的另一种方法

%% multiplyAndSum(A,B,Result,Count) when length(A) =:= length(B) ->

%% case 0 =:= Count of

%% true -> Result;

%% false ->

%% Sum = Result ++ lists:nth(Count,A)*lists:nth(Count, B),

%% multiplyAndSum(A,B,Sum,Count-1)

%% end.

%% 总结:(1)erlang多进程的消息交互

%% (2)如何统计erlang进程邮箱中接收到消息的数量,本例中的loop方法

%% (3)erlang递归计数问题词的训练
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: