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

Rad*_*dek 2 concurrency erlang multithreading

目前,我正在阅读"编程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.
Run Code Online (Sandbox Code Playgroud)

我在Windows 7 x64上安装了英特尔i5,在创建了1亿个进程时,我检查了CPU的负载.事实证明,只有一个核心满负荷运行,其他核心无效(因此整体系统负载为25%).我认为Erlang VM会平衡所有4个可用内核的负载,但事实并非如此.

有人知道为什么吗?我的Erlang VM配置有什么不好的地方吗?

rvi*_*ing 6

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

你可以看到这一点的一种方式是,你开始100M流程,同时默认的系统只允许34K〜过程在同一时间.

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

拥有大量流程并不能保证应用程序中的并行性,请参阅Amdahl定律来描述问题.