【发布时间】:2021-02-03 02:46:41
【问题描述】:
我正在学习 Erlang,并且对并行化工作的轻松程度印象深刻。为了练习一下,我挖出了很好的旧 Fibanocci 序列。在下面的代码中,我尝试通过一次计算三个昂贵的产品来利用并行化。
-module (fib4).
-export ( [main/1] ).
main (N) ->
fib (list_to_integer (atom_to_list (hd (N) ) ) ),
halt (0).
path (1, Acc) -> Acc;
path (N, Acc) when N rem 2 =:= 0 ->
path (N - 1, [step | Acc] );
path (N, Acc) ->
path ( (N - 1) div 2, [jump | Acc] ).
fib (N) -> fib (1, 1, path (N, [] ) ).
fib (N, Nplus1, [Last] ) ->
case Last of
step -> Nplus1;
jump -> N * N + Nplus1 * Nplus1
end;
fib (N, Nplus1, [jump | T] ) ->
Pid = self (),
spawn (fun () -> Pid ! {n1sq, Nplus1 * Nplus1} end),
spawn (fun () -> Pid ! {mul, 2 * N * Nplus1} end),
spawn (fun () -> Pid ! {nsq, N * N} end),
{Nsq, N1sq, Mul} = loop (0, 0, 0),
fib (Nsq + N1sq, N1sq + Mul, T);
fib (N, Nplus1, [step | T] ) ->
fib (Nplus1, N + Nplus1, T).
loop (Nsq, N1sq, Mul) ->
receive
{nsq, Val} ->
if
N1sq > 0 andalso Mul > 0 -> {Val, N1sq, Mul};
true -> loop (Val, N1sq, Mul)
end;
{n1sq, Val} ->
if
Mul > 0 andalso Nsq > 0 -> {Nsq, Val, Mul};
true -> loop (Nsq, Val, Mul)
end;
{mul, Val} ->
if
N1sq > 0 andalso Nsq > 0 -> {Nsq, N1sq, Val};
true -> loop (Nsq, N1sq, Val)
end
end.
我在 Phenom X4 上运行此代码,在我的机器上计算 fib(10000000) 的那一刻,只有一到两个内核在工作,其他内核在闲置。
我的问题是:
- 谁来决定分配工作线程的核心数? Erlang 节点或我的操作系统(在我的情况下是 2.6.38 的 ubuntu)?
- 是否会因为两个或三个内核处于空闲状态而导致速度下降?
【问题讨论】:
标签: erlang parallel-processing