如何获得并发函数(pmap)来使用Elixir中的所有核心?

use*_*584 3 concurrency performance elixir pmap iex

我是Elixir的新手,我开始阅读Dave Thomas的优秀编程Elixir.我很好奇我可以在多大程度上采用"pmap"函数的并发性,所以我迭代地将项目数量从1,000增加到10,000,000.出于好奇,我观察了输出,htop正如我所做的那样,通常会出现类似于下图所示的CPU使用率:

htop输出

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

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

我的问题是,为什么我的机器上只有核心1,3,5和7点亮了?我的猜测是,它与我的iex流程只是一个操作系统级别的流程有关,OSX正在管理该流程的范围.那是怎么回事?有没有办法确保所有内核都用于执行性能密集型任务?

tko*_*wal 9

@Thiago Silveira关于iex输出的第一行的好评.该部分[smp:8:8]说明了Erlang使用了多少操作系统级进程.--smp如果要禁用它,可以使用flag控制它:

iex --erl '-smp disable'
Run Code Online (Sandbox Code Playgroud)

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

iex --erl '+S 1:1'
Run Code Online (Sandbox Code Playgroud)

每个操作系统进程都需要有自己的Erlang进程调度程序,因此您可以轻松查看当前有多少个进程:

:erlang.system_info(:schedulers_online)
Run Code Online (Sandbox Code Playgroud)

回答关于表现的问题.如果您的处理器没有满负荷运行(100%)而且没有处理器(0%),则很可能使负载分布更均匀不会加快速度.为什么?

通过在许多时间点探测处理器状态来测量CPU使用率.这种状态要么"工作"要么"闲置".82%的CPU使用率意味着您可以在此CPU上执行更多任务,而不会降低其他任务的速度.

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

接下来可能导致奇数和偶数内核之间存在巨大差异的是超线程.在我的双核处理器上htop显示4个逻辑核心.在您的情况下,由于HT,您可能有4个物理核心和8个逻辑核心.可能是您正在使用100%的物理核心.

另一件事:pmap需要在单独的进程中计算结果,但最后它将它发送给调用者,这可能是一个瓶颈.发送消息的次数越多,可以实现的CPU利用率越低.您可以尝试为过程提供一个非常耗费CPU的任务,例如计算Ackerman函数.您甚至可以使用Amdahl定律和不同数量的核心测量执行时间来计算您的工作量是连续部分的数量,以及并行数量.

总结一下:截图的CPU利用率看起来真的很棒!您不必为更多性能密集型任务更改任何内容.