Erlang на многоядерном ЦП

Я изучаю эрланг и очень впечатлен тем, насколько легко распараллелить работу. Чтобы немного попрактиковаться, я откопал хорошую последовательность Фибаноччи. В следующем коде я пытаюсь воспользоваться преимуществом распараллеливания, вычисляя по три дорогостоящих продукта за раз.

-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) только один до двух ядер работают, а остальные бездействуют.

enter image description here

Мои вопросы:

  • Кто решает, на сколько ядер распределяются рабочие потоки? Узел erlang или моя ОС (ubuntu с 2.6.38 в моем случае)?
  • Я теряю скорость из-за того, что два или три ядра простаивают?
17
задан Hyperboreus 10 August 2011 в 04:03
поделиться