<br><br><div class="gmail_quote">On Tue, Mar 4, 2008 at 4:54 PM, Allen McPherson <<a href="mailto:mcpherson@lanl.gov">mcpherson@lanl.gov</a>> wrote:<br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
-- Re-post.  Hope I don't generate a duplicate post but I just signed<br>
up.<br>
<br>
<br>
Hello,<br>
<br>
First post here from a new Erlang programmer.  As an exercise I<br>
have written the message ring benchmark that Joe talked about in<br>
his book:<br>
<br>
-module(cleanring).<br>
-compile(export_all).<br>
<br>
start(N, Msg) -><br>
     StartPid = launch(self(), N),<br>
     StartPid ! {Msg, self(), 0},<br>
     receive<br>
        {MsgRecvd, _FromPid, _Hop} -> done<br>
     end,<br>
     StartPid ! die,<br>
     MsgRecvd.<br>
<br>
launch(Pid, N) -><br>
     FromPid = spawn(fun() -> loop(Pid) end),<br>
     if<br>
        N =:= 1 -> FromPid;<br>
        true    -> launch(FromPid, N-1)<br>
     end.<br>
<br>
loop(ToPid) -><br>
     receive<br>
        {Term, _FromPid, Hop} -><br>
            ToPid ! {Term, self(), Hop+1},<br>
            loop(ToPid);<br>
        die -><br>
            ToPid ! die<br>
     end.<br>
<br>
<br>
If I run as follows, it dies in malloc:<br>
<br>
1> c(cleanring).<br>
2> L = lists:seq(1,100000).<br>
3> cleanring:start(32000, L).<br>
<br>
If I make L a binary (in a restarted erl shell) it runs fine (and too<br>
fast to believe):<br>
<br>
1> c(cleanring).<br>
2> L = lists:seq(1,100000).<br>
3> LL = term_to_binary(L).<br>
4> cleanring:start(32000, LL).<br>
<br>
Is the runtime somehow just passing around a pointer to LL by virtue<br>
of it being a binary?  I'm not sure why it doesn't crash as the first<br>
run did.<br>
<br></blockquote><div>You are right, binary messages are send only by passing pointer, but normal structures don't. Normal structures are send by copying because shared nothing processes strategy. Erlang GC don't free message immediately but after some amount of reductions (function calls) and your receive loop in each process is reduced only one time than your big message is kept in memory.<br>
<br>Possible solution is explicit garbage collect after message send but it decrease performance for small messages (more than 20%):<br><br>loop(ToPid) -><br>    receive<br>       {Term, _FromPid, Hop} -><br>           ToPid ! {Term, self(), Hop+1},<br>
           garbage_collect(), % explicit garbage collect message<br>           loop(ToPid);<br>       die -><br>           ToPid ! die<br>    end.<br><br></div><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">

Also, if you spot anything really wrong with the program I'd<br>
appreciate a<br>
heads up.  I'm new to Erlang and am sometimes not sure if the code I<br>
write<br>
is in the "right mindset" (functional programming-wise).</blockquote><div> </div><div>I think your program is OK, but when you must pass many times huge message, good strategy is avoid this or send binary.<br></div>
<blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;"><br>
Thanks<br>
<font color="#888888">--<br>
Al<br>
<br>
_______________________________________________<br>
erlang-questions mailing list<br>
<a href="mailto:erlang-questions@erlang.org">erlang-questions@erlang.org</a><br>
<a href="http://www.erlang.org/mailman/listinfo/erlang-questions" target="_blank">http://www.erlang.org/mailman/listinfo/erlang-questions</a><br>
</font></blockquote></div><br><br clear="all"><br>-- <br>--Hynek (Pichi) Vychodil