目前,我正在阅读“编程Erlang”一书,我决定在一个创建N个进程的基准测试中测试我的系统,这里是代码:
-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
ok ->
ok
end.
我在Windows 7 x64上安装了Intel i5,在创建了1亿个进程时,我检查了CPU的负载。事实证明,只有一个核心满负荷运行,其他核心无效(因此整体系统负载为25%)。我认为Erlang VM会平衡所有4个可用内核的负载,但事实并非如此。
有人知道为什么吗?我的Erlang VM的配置有什么不好吗?
答案 0 :(得分:6)
我认为限制这个例子的并行性的一件事是实际上很少有并行工作。每个进程生成链中的下一个进程,立即向其发送ok
消息。这意味着在生成下一个进程后的下一个进程将收到ok
并终止。因此,事实上,并不会有很多进程实际同时运行。
您可以看到这种情况的一种方式是您正在启动100M进程,而默认系统只允许同时进行〜34k进程 。
更好的测试是启动一个响铃进程,每个进程生成下一个进程并进入循环,接收消息并将其发送到下一个进程。然后,您将在同一时间运行整个环。为了获得正确的并行活动,环的头部必须在环之前发送大量消息,然后才开始从环中接收它们。如果您一次发送一个消息,那么一次只能有一个进程正在工作。
拥有大量进程并不能保证应用程序中的并行性,请参阅Amdahl's law以获取问题的描述。