Currently, I am reading a "Programming Erlang" book and I decided to test my system in a benchmark which creates N number of processes, here is the code:
-module(my_ring).
-export([start/1, start_proc/2]).
start(Num) ->
start_proc(Num, self()).
start_proc(0, Pid) ->
Pid ! ok;
start_proc(Num, Pid) ->
NPid = spawn(?MODULE, start_proc, [Num - 1, Pid]),
NPid ! ok,
receive
开发者_JAVA技巧 ok ->
ok
end.
I have Intel i5 on Windows 7 x64 and, while creating 100 000 000 of processes, I checked load of my CPU. It turned out that only one core works at full capacity, others do nothing (so overall system load is 25%). I thought that Erlang VM would balance the load across all of 4 avaible cores, but it doesn't.
Does anybody know why? Is there anything bad with configurations of my Erlang VM?
I think that one thing which limits the parallelism of this example is that there is actually very little parallel work being done. Each process spawns the next process in the chain and immediately sends it an ok
message. This means that next process after having spawned its next process will receive an ok
and terminate. So, in fact, there won't be many processes actually running concurrently.
One way you can see this is that you are starting 100M processes while the default system only allows ~34k processes at the same time.
A better test would be to start a ring processes where each one spawns the next process and goes into loop where it receives a message and sends it to the next process. You would then have the whole ring running at the same time. To get the proper parallel activity the head of the ring would have to send a large number of messages around the ring before it starts receiving them out of the ring. If you sent one message at a time around the ring there would still only be one process at a time doing work.
Having a lot of processes is no guarantee for parallelism in your application, see Amdahl's law for a description of the problem.
精彩评论