多核CPU上的Erlang [英] Erlang on multicore CPU

查看:213
本文介绍了多核CPU上的Erlang的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在学习erlang,并且印象深刻的是,平行工作是多么容易。要练习一下,我挖出了好的Fibanocci序列。在以下代码中,我尝试通过一次计算三个昂贵的产品来实现并行化。

  -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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆