Write a ring benchmark. Create N processes in a ring. Send a mes- sage round the ring M times so that a total of N * M messages get sent. Time how long this takes for different values of N and M.My solution is below... It was fun.
Usage from erlang command line
1> c(ring2). 2> ring2:start(100, 1000). % ring size = 100, send msg 1000 times round the ring ... sample below ... 42> ring2:start(300, 2000). Starting ring benchmark on pid=<0.30.0>. Done initializing nodes. Got X(600000) >= M(600000) in pid=<0.30.0>. Done running ring benchmark in Wall Clock = 437, Runtime = 391. ok
The results above were obtained on a Core 2 Duo E8400 @ 3.00GHz
ring2.erl
-module(ring2).
-include("debug.hrl").
-export([start/2]).
%% ring benchmark
start(N, M) ->
    io:format("Starting ring benchmark on pid=~p.~n", [self()]),
    statistics(wall_clock),
    statistics(runtime),
    NextPid = node(N-1, N*M, self(), self()),
    NextPid ! 1,
    io:format("Done initializing nodes.~n"),
    wait(N*M, NextPid, self()),
    NextPid ! die,
    {_, WC} = statistics(wall_clock),
    {_, RT} = statistics(runtime),
    io:format("Done running ring benchmark in Wall Clock = ~p, Runtime = ~p.~n", [WC, RT]).
     
node(1, M, NextPid, DonePid) ->
    Pid = spawn(fun () -> wait(M, NextPid, DonePid) end),
    ?DEBUG("Creating final node: ~p.~n", [Pid]),
    Pid;
node(N, M, NextPid, DonePid) -> 
    Pid = spawn(fun () -> wait(M, NextPid, DonePid) end),
    ?DEBUG("Creating node ~p = ~p.~n", [N, Pid]),
    node(N-1, M, Pid, DonePid).
wait(M, NextPid, DonePid) ->
    receive
 die ->
     ?DEBUG("~p dying.~n", [self()]),
     if NextPid =/= DonePid -> NextPid ! die;
        true -> void
     end,
     void;
 X when X >= M -> 
     io:format("Got X(~p) >= M(~p) in pid=~p.~n", [X, M, self()]),
     DonePid ! die,
     wait(M, NextPid, DonePid);
 X   ->
     ?DEBUG("Got X = ~p in pid=~p, fwd to ~p.~n", [X, self(), NextPid]),
     NextPid ! X+1,
     wait(M, NextPid, DonePid)
    end.     
I am using a little debugging macro to turn logging on/off. At erlang shell: c(ring2, {d, debug}). to turn debugging trace on.
debug.hrl
-ifdef(debug).
-define(DEBUG(Format, Args), io:format("~s.~w: DEBUG: " ++ Format, [ ?MODULE, ?LINE | Args])).
-else.
-define(DEBUG(Format, Args), true).
-endif.
here are some solutions from other people: http://goo.gl/kE42w
No comments :
Post a Comment