What are the numbers on an SMP VM with >2 schedulers?<br><br><div><span class="gmail_quote">On 9/10/07, <b class="gmail_sendername">David King</b> <<a href="mailto:dking@ketralnis.com">dking@ketralnis.com</a>> wrote:
</span><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">> The problem here is that you are insisting on receiving messages by<br>> a given order: {msg, X} with X <- [1..N]. Messages sent become
<br>> interleaved in the mailbox; when you try to remove, say {msg,<br>> 40000} from the 1st process, there are already 10000s of messages<br>> in the mailbox from the other process before that one, that must be<br>
> scanned; receive becomes very slow.<br><br>Ah, I can see that, and I can see why, as now it is the messages out<br>of order, so expecting to be able to receive them in order is silly<br><br>> This is one of the problems one must be keeping an eye on: beware
<br>> the size of the mailbox. In your problem you will see that if you<br>> replace receive by<br>> receive {msg, _} -> ok end<br>> the program will execute extremely fast, as with 1 process.
<br><br>Yes, it does, now sending with two processes is just as fast as<br>sending with one (and when I actually have work to do as I receive<br>them, it will be faster). And in my use-case, receiving the messages<br>out-of-order isn't a problem at all.
<br><br>Thank you for the advice.<br><br><br>> David King wrote:<br>>> I've noticed that I can send 100,000 messages from one process to<br>>> another very quickly (less than a second), but if I have two
<br>>> process send 50,000 messages each to a given process, it receives<br>>> them very slowly (in my test, 36s). I found this using the<br>>> mapreduce implementation in Joe's book where potentially
<br>>> thousands of processes are spawned and many (potentially very<br>>> small) messages are sent.<br>>> I assume that this is because the message queue is locked while<br>>> sending and receiving messages. Is there any way to work around
<br>>> this so that having multiple processes sending many messages each<br>>> isn't so slow? In my case I'd like the sender and receiver to be<br>>> working simultaneously, so having each sender process send one
<br>>> large list isn't quite as efficient<br>>> Here it is with one process:<br>>> (nodename@ayla)11> message_streamer:stream_messages(100000).<br>>> Receiving 10000 at 63356401790<br>>> Receiving 20000 at 63356401790
<br>>> Receiving 30000 at 63356401790<br>>> Receiving 40000 at 63356401790<br>>> Receiving 50000 at 63356401790<br>>> Receiving 60000 at 63356401790<br>>> Receiving 70000 at 63356401790<br>>> Receiving 80000 at 63356401790
<br>>> Receiving 90000 at 63356401790<br>>> Done sending 100000 messages<br>>> Receiving 100000 at 63356401790<br>>> 100000 messages in 1s, 1.00000e+5 msg/s<br>>> And here it is with two processes:
<br>>> (nodename@ayla)9> message_streamer:stream_messages(100000).<br>>> Receiving 10000 at 63356401639<br>>> Receiving 20000 at 63356401643<br>>> Receiving 30000 at 63356401650<br>>> Receiving 40000 at 63356401660
<br>>> Receiving 50000 at 63356401673<br>>> Done sending 50000 messages<br>>> Receiving 60000 at 63356401673<br>>> Receiving 70000 at 63356401673<br>>> Receiving 80000 at 63356401673<br>>> Receiving 90000 at 63356401673
<br>>> Receiving 100000 at 63356401673<br>>> Done sending 50000 messages<br>>> 100000 messages in 36s, 2777.78 msg/s<br>>> In the multiple-process case, it actually slows down as more<br>>> messages are sent until one of the processes completes, and then
<br>>> it receives them all very quickly. Here's the code:<br>>> --- code begins ---<br>>> -module(message_streamer).<br>>> -compile(export_all).<br>>> stream_messages(N) -><br>>> Self=self(),
<br>>> Start=myapp_util:now(),<br>>> List=lists:seq(1,N),<br>>> Split_List=split_list(List,erlang:system_info(schedulers)),<br>>> lists:foreach(fun(Sublist) -><br>>> spawn_link(fun() ->
<br>>> lists:foreach(fun(Which) -><br>>> Self ! {msg,Which}<br>>> end,<br>>> Sublist),
<br>>> io:format("Done sending ~p messages~n",<br>>> [length(Sublist)])<br>>> end)<br>>> end, Split_List),<br>>> lists:foreach(fun(Which) ->
<br>>> case Which rem (N div 10) of<br>>> 0 -><br>>> io:format("Receiving ~p at ~p ~n",<br>>> [Which,myapp_util:now()]);
<br>>> _ -> ok<br>>> end,<br>>> receive {msg,Which} -> ok end<br>>> end,<br>>> List),
<br>>> Time=case myapp_util:now()-Start of<br>>> 0 -> 1;<br>>> X -> X<br>>> end,<br>>> io:format("~p messages in ~ps, ~p msg/s~n",[N,Time,N/Time]).
<br>>> %% splits a list into equal parts<br>>> %% split_list([1,2,3,4,5,6],2) -> [[1,2,3],[4,5,6]]<br>>> split_list(List,Pieces) -><br>>> Length=length(List),<br>>> lists:reverse(split_list(List,Length div Pieces,Length,[])).
<br>>> split_list([], _Per_Piece, 0, Acc) -><br>>> Acc;<br>>> split_list(List, Per_Piece, Length, Acc) when Length>=Per_Piece -><br>>> {Short,Long} = lists:split(Per_Piece,List),<br>
>> split_list(Long, Per_Piece, Length-Per_Piece, [ Short | Acc ]);<br>>> split_list(List, Per_Piece, Length, Acc) when Length <Per_Piece -><br>>> {Short,Long} = lists:split(Length, List),<br>
>> split_list(Long, Per_Piece, Length-Length, [ Short | Acc ]).<br>>> --- code ends ---<br>>> myapp_util:now() just looks like:<br>>> now() -><br>>> calendar:datetime_to_gregorian_seconds(calendar:universal_time()).
<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">
http://www.erlang.org/mailman/listinfo/erlang-questions</a><br>><br>><br>> --<br>> Paulo Sérgio Almeida Email:<br>> <a href="mailto:psa@di.uminho.pt">psa@di.uminho.pt</a><br>> Dep. Informatica - Universidade do Minho Phone: +351 253
<br>> 604451<br>> Campus de Gualtar - 4710-057 Braga - PORTUGAL Fax : +351 253<br>> 604471<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">http://www.erlang.org/mailman/listinfo/erlang-questions</a><br></blockquote></div><br>