2016-04-24 114 views
3

我是Elixir的新手,我开始阅读Dave Thomas的优秀编程Elixir。我很好奇我可以在多大程度上采用“pmap”函数的并发性,所以我反复将项目数量从1,000增加到了10,000,000。出于好奇,我看到的htop输出作为我这样做,通常以类似于CPU使用率达到顶点如下图所示:如何获得并发功能(pmap)以使用Elixir中的所有内核?

htop output

显示书中的例子后,戴夫说:

而且,是的,我刚刚启动了1000个后台进程,并且使用了我机器上的所有内核和处理器。

我的问题是,如何在我的机器上只有核心1,3,5和7点亮?我的猜测是,它与我的iex进程只是一个OS级进程有关,而OSX正在管理该进程的范围。这是怎么回事?有什么方法可以确保所有内核都用于性能密集型任务?

+0

iex的输出的第一行是什么?即: “二郎/ OTP 18 [专家评审组-7.3] [源] [64位] [SMP:4:4] [异步线程:10] [HIPE] [内核轮询:假] [则dtrace]” –

+0

@ ThiagoSilveira'二郎/ OTP 18 [专家评审组-7.3] [源] [64位] [SMP:8:8] [异步线程:10] [HIPE] [内核轮询:假] [则dtrace]' – user456584

回答

8

@Thiago Silveira关于iex输出的第一行的评论。部分[smp:8:8]表示Erlang使用了多少操作系统级别的进程。如果要禁用它,你可以用标志--smp控制这样的:

iex --erl '-smp disable' 

这将确保你只有一个系统的过程。您可以通过启用对称多处理来实现类似的结果,但直接设置为NumberOfShcedulers:NumberOfSchedulersOnline

iex --erl '+S 1:1' 

每个操作系统进程需要有它自己的Erlang进程调度程序,所以你可以很容易地看到有多少人你有目前:

:erlang.system_info(:schedulers_online) 

要回答你关于性能的问题。如果你的处理器不能满负荷工作(100%),并且它们中的任何一个都没有做任何事情(0%),那么很可能使负载更均匀分布不会加快速度。为什么?

通过在多个时间点探测处理器状态来测量CPU使用率。这个状态是“正在工作”或“空闲”。 82%的CPU使用率意味着您可以在该CPU上执行多项任务而不会减慢其他任务。

Erlang调度器试图变得聪明,不会在核心之间迁移Erlang进程,除非他们必须因为它需要复制。例如,当调度程序中的一个空闲时,就会发生迁移。然后它可以借用其他调度程序运行队列中的进程。

接下来可能会导致奇数核心和偶数核心之间出现如此大的差异的是超线程。在我的双核心处理器htop显示4个逻辑核心。在你的情况下,你可能有4个物理内核和8个逻辑因为HT。这可能是你正在使用100%物理内核的情况。

另一件事:pmap需要在单独的进程中计算结果,但最终将它发送给调用者,这可能是一个瓶颈。发送消息越多,可以达到的CPU利用率就越少。您可以尝试一下,让流程执行一项真正耗费CPU资源的任务,如计算Ackerman function。你甚至可以计算出你的工作有多少是顺序部分,以及使用Amdahl's law并行计算多少并针对不同数量的内核测量执行时间。

综上所述:从截图的CPU利用率看起来真的很棒!您不需要为更多性能密集型任务更改任何内容。

+1

非常有见地答案 - 谢谢! – user456584

2

并发不平行

为了获得良好的并行性能进行药剂/ BEAM的编码,你需要有束调度是如何工作的一些认识。

这是一个非常简单的模型,但波束调度给每个进程2000和削减它换出下一个工序的过程之前。减少可以被认为是函数调用。默认情况下,进程在产生它的核心/调度程序上运行。如果在给定的调度程序上构建未完成进程的队列,那么进程只会在调度程序之间移动。默认情况下,BEAM在每个可用核心上运行调度线程。

什么意味的是,为了获得最大的使用,你需要你的任务分解成足够大幅作品将超过工作的标准“减排”片的处理器。一般来说,当你将许多项目分成一个单独的任务时,pmap风格的并行性只会显着加速。

另一件需要注意的事情是BEAM的某些部分在等待工作时使用旋转/等待循环,并且在使用 工具(如htop)检查CPU使用情况时可能会歪曲使用情况。使用:observer可以更好地了解您的程序性能。

相关问题