Erlang在运行并发任务时没有使用所有CPU核心,为什么?
目前,我正在阅读一本“Programming 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,同时创建了 100 000 000 个进程,我检查了 CPU 的负载。事实证明,只有一个核心满负荷工作,其他核心什么也不做(因此系统总体负载为 25%)。我认为 Erlang VM 会平衡所有 4 个可用核心的负载,但事实并非如此。
有人知道为什么吗?我的 Erlang VM 配置有什么问题吗?
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
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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我认为限制此示例并行性的一件事是实际上很少有并行工作正在完成。每个进程都会生成链中的下一个进程,并立即向其发送一条
ok
消息。这意味着下一个进程在生成其下一个进程后将收到ok
并终止。所以,事实上,实际上不会有很多进程同时运行。可以看到这一点的一种方法是,您正在启动 100M 进程,而默认系统仅允许同时运行约 34k 进程。
更好的测试是启动一个环形进程,其中每个进程生成下一个进程并进入循环,在循环中接收消息并将其发送到下一个进程。然后整个环就会同时运行。为了获得正确的并行活动,环的头部必须在开始从环中接收消息之前在环周围发送大量消息。如果您在环路中一次发送一条消息,那么一次仍然只有一个进程在工作。
拥有大量进程并不能保证应用程序中的并行性,请参阅阿姆达尔定律了解问题的描述。
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 anok
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.