Erlang计划如何在多核CPU机器上工作? [英] How does Erlang schedule work for multicore CPU machines?

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

问题描述

我正在学习Erlang,这给并行化工作变得多么容易留下了深刻的印象.为了进行一些练习,我挖掘了旧的斐波那契序列.在下面的代码中,我尝试通过一次计算三个昂贵的产品来利用并行化.

 -模块(fib4).-export([main/1]).主(N)->fib(list_to_integer(atom_to_list(hd(N)))),停止(0).路径(1,Acc)->Acc;当N rem 2 =:= 0时,路径(N,Acc)= 0.路径(N-1,[step | Acc]);路径(N,Acc)->路径((N-1)div 2,[jump | Acc]).fib(N)->fib(1,1,路径(N,[])).fib(N,Nplus1,[Last])->案件的最后步骤->Nplus1;跳->N * N + Nplus1 * Nplus1结尾;fib(N,Nplus1,[jump | T])->Pid =自我(),产生(fun()-> Pid!{n1sq,Nplus1 * Nplus1}结尾),spawn(fun()-> Pid!{mul,2 * N * Nplus1}结尾),spawn(fun()-> Pid!{nsq,N * N}结尾),{Nsq,N1sq,Mul} =循环(0,0,0),fib(Nsq + N1sq,N1sq + Mul,T);fib(N,Nplus1,[step | T])->fib(Nplus1,N + Nplus1,T).循环(Nsq,N1sq,Mul)->收到{nsq,Val}->如果N1平方0并且Mul>0->{Val,N1sq,Mul};正确->循环(Val,N1sq,Mul)结尾;{n1sq,Val}->如果穆尔>0并且Nsq>0->{Nsq,Val,Mul};正确->循环(Nsq,Val,Mul)结尾;{mul,Val}->如果N1平方0并且Nsq>0->{Nsq,N1sq,Val};正确->循环(Nsq,N1sq,Val)结尾结尾. 

我正在Phenom X4上运行此代码,并且在我的计算机上计算 fib(10000000)的那一刻,只有一个到两个内核在工作,而其他内核却在闲逛.

>

我的问题是:

  • 谁来决定将工作线程分配给多少个内核?是Erlang节点还是我的操作系统(在我的情况下为ubuntu 2.6.38)?
  • 由于两个或三个内核处于空闲状态,我是否会失去速度?

解决方案

Erlang的默认行为在历史上一直是运行一个调度程序,该调度程序基本上是本机OS线程,它从队列中选择要运行的Erlang任务.随着多核和多处理器系统的出现,运行时间得以扩展以利用.在启用 -smp 的情况下启动运行时,将导致运行时创建多个调度程序,通常每个逻辑CPU一个.您可以使用 -S 标志手动指定调度程序的数量,例如 -S 16 .

《 Erlang运行时系统参考手册》 中对此进行了记录.

可以在此更深入地讨论SMP支持.讨论主题.

编辑

我还应该指出,从R12B开始,默认情况下在支持SMP的平台上启用SMP(相当于 -smp auto 标志).如果您对自己的运行时感到好奇,那么以下讨论线程中的引文将很有趣:

您可以在打印输出的第一行看到选择的内容."erl"命令.例如.erlang(BEAM)模拟器版本5.6.4 [源代码] [smp:4] [异步线程: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 old 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 lose 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.

这篇关于Erlang计划如何在多核CPU机器上工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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