多核CPU上的Erlang [英] Erlang on multicore CPU
问题描述
-module(fib4) 。
-export([main / 1])。
main(N) - >
fib(list_to_integer(atom_to_list(hd(N)))),
halt(0)。
path(1,Acc) - >加速;
path(N,Acc)当N rem 2 =:= 0 - >
path(N - 1,[step | Acc]);
path(N,Acc) - >
path((N - 1)div 2,[jump | Acc])。
fib(N) - > fib(1,1,路径(N,[]))。
fib(N,Nplus1,[Last]) - >
case最后
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) - >
接收
{nsq,Val} - >
如果
N1sq> 0 andalso Mul> 0 - > {Val,N1sq,Mul};
true - >循环(Val,N1sq,Mul)
end;
{n1sq,Val} - >
如果
Mul> 0和等于Nsq> 0 - > {Nsq,Val,Mul};
true - >循环(Nsq,Val,Mul)
end;
{mul,Val} - >
如果
N1sq> 0和等于Nsq> 0 - > {Nsq,N1sq,Val};
true - >循环(Nsq,N1sq,Val)
end
end。
我在Phenom X4上运行此代码,在我的机器上计算fib (10000000)只有一到两个内核正在工作,其他的都在空转。
- 谁决定分配多少个内核的工作线程? erlang节点或我的操作系统(ubuntu 2.6.38在我的情况)?
- 由于两个或三个内核空闲的事实,我的速度是否松动?
Erlang的默认行为历来是运行一个调度程序,这是一个本机OS线程,它选择Erlang任务从队列中运行。随着多核处理器和多处理器系统的出现,运行时被扩展到可以利用。启动 -smp启动运行时
将导致运行时创建多个调度程序,通常每个逻辑CPU一个。您可以手动指定具有 -S
标志的调度程序的数量。 -S 16
。
这是在 Erlang运行时系统参考手册。
有关SMP支持的更深入的讨论可以在此讨论话题。
编辑
我还应该指出,从R12B开始,默认情况下,SMP在支持的平台上启用它(相当于 -smp auto
标志)。如果您对自己的运行时间感到好奇,讨论主题的以下引用将令人感兴趣:
您可以看到所选的内容在
erl命令的第一行打印输出。例如。
Erlang(BEAM)仿真器版本5.6.4 [源] [smp:4] [asynch-threads:0] .....
上面的[smp:4]说明了SMP VM的运行和4个调度程序。
I am learning erlang and am quite impressed how easy it is to parallelize work. To practice a bit I dug up the good ole Fibanocci sequence. In the following code I try to take advantage of parallelization by computing the expensive products three at a time.
-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.
I am running this code on a Phenom X4 and during the minute it takes on my machine to calculate fib (10000000) only one to two cores are working and the others are idling around.
My questions are:
- Who decides onto how many cores the worker threads are distributed? The erlang node or my OS (ubuntu with 2.6.38 in my case)?
- Do I loose speed due to the fact that two or three cores are idling?
Erlang's default behavior has historically been to run one scheduler, which is basically a native OS thread, which chooses Erlang tasks to run from a queue. With the advent of multi-core and multi-processor systems, the runtime was extended to take advantage. Starting the runtime with -smp enabled
will cause the runtime to create multiple schedulers, usually one per logical CPU. You can manually specify the number of schedulers with the -S
flag e.g. -S 16
.
This is documented in the Erlang Run-Time System Reference Manual.
A deeper discussion of SMP support can be found in this discussion thread.
EDIT
I should also point out that, as of R12B, SMP is enabled by default on platforms that support it (equivalent to the -smp auto
flag). If you're curious about your own runtime, the following quote from the discussion thread will be of interest:
You can see what was chosen at the first line of printout from the "erl" command. E.g. Erlang (BEAM) emulator version 5.6.4 [source] [smp:4] [asynch-threads:0] .....
The "[smp:4]" above tells that the SMP VM is run and with 4 schedulers.
这篇关于多核CPU上的Erlang的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!