リングベンチマーク

Nこのプロセスをリング上につないで,Mステップリングを回るメッセージをそれぞれ送る問題のベンチマーク
Programming Erlangにあったやつ。

-module(ring).
-compile(export_all).

for(N, F) -> for(N, F, []).
for(0, _, L) -> L;
for(N, F, L) -> for(N-1, F, [F() | L]).

make_node(M, Parent) ->
    spawn(fun() -> 
                  receive NextPid -> 
                          node_loop(M, NextPid, Parent)
                  end
          end
         ).

node_loop(0, _, Parent) -> Parent ! {self(), finish};
node_loop(M, NextPid, Parent) ->
    receive
        {0, _Msg} -> node_loop(M-1, NextPid, Parent);
        {C, Msg} -> 
%%             io:format("~p receive ~p: ~p~n", [self(), C, Msg]),
            NextPid ! {C-1, Msg},
            node_loop(M-1, NextPid, Parent)
    end.


start(N, M) ->
    Nodes = for(N, fun() -> make_node(M, self()) end),
    %% set neighbor
    Last = lists:foldl(fun(Pid, PrePid) -> Pid ! PrePid, Pid end,
                       hd(Nodes),
                       tl(Nodes)),
    hd(Nodes) ! Last,
    statistics(runtime),
    statistics(wall_clock),
    %% send message
    lists:zipwith(fun(Pid,I) -> Pid ! {M, {message, I}} end,
                  Nodes,
                  lists:seq(1,N)),
    %% wait all
    lists:foreach(fun(Pid) -> receive {Pid, finish} -> void end end,
                  Nodes),
    {_, RunTime} = statistics(runtime),
    {_, WallTime} = statistics(wall_clock),
    io:format("ring benchmark : ~p (~p) miliseconds~n", [RunTime, WallTime]).

N \ M 1000 2000
10 10 10
100 70 110
1000 970 1810
10000 10280 21130
20000 21300 42940

Pentium 4 2.4GHz, メモリ1G,
時間はプロセス数に関してほぼ線形。
メッセージ数1000の時,プロセスを100K個にしても,メモリが100MBしか増えない。この場合は1プロセス1KBになっ
ている.