Erlang在运行并发任务时没有使用所有cpu核心,为什么?

时间:2011-04-17 22:02:26

标签: multithreading concurrency erlang

目前,我正在阅读“编程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的配置有什么不好吗?

1 个答案:

答案 0 :(得分:6)

我认为限制这个例子的并行性的一件事是实际上很少有并行工作。每个进程生成链中的下一个进程,立即向其发送ok消息。这意味着在生成下一个进程后的下一个进程将收到ok并终止。因此,事实上,并不会有很多进程实际同时运行。

您可以看到这种情况的一种方式是您正在启动100M进程,而默认系统只允许同时进行〜34k进程

更好的测试是启动一个响铃进程,每个进程生成下一个进程并进入循环,接收消息并将其发送到下一个进程。然后,您将在同一时间运行整个环。为了获得正确的并行活动,环的头部必须在环之前发送大量消息,然后才开始从环中接收它们。如果您一次发送一个消息,那么一次只能有一个进程正在工作。

拥有大量进程并不能保证应用程序中的并行性,请参阅Amdahl's law以获取问题的描述。