Erlang因能够支持许多轻量级进程而闻名.它可以做到这一点,因为它们不是传统意义上的进程,甚至不是P线程中的线程,而是完全在用户空间中的线程.
这很好(实际上太棒了).但是,如何在多核/多处理器环境中并行执行Erlang线程?当然它们必须以某种方式映射到内核线程才能在不同的内核上执行?
假设情况就是这样,这是怎么做到的?许多轻量级进程是否映射到单个内核线程?
或者还有另一种解决这个问题的方法吗?
答案取决于使用的VM:
1)非SMP:有一个调度程序(OS线程),它执行所有Erlang进程,取自可运行进程池(即那些未被例如阻塞的进程receive
)
2)SMP:有K个调度程序(OS线程,K通常是许多CPU内核),它们从共享进程队列执行Erlang进程.它是一个简单的FIFO队列(带有锁,允许从多个OS线程同时访问).
3)R13B和更新版本中的SMP:将有K个调度程序(如前所述)从多个进程队列执行Erlang进程.每个调度程序都有自己的队列,因此将添加从一个调度程序到另一个调度程序的进程迁移逻辑.此解决方案将通过避免共享进程队列中的过度锁定来提高性能.
有关更多信息,请参阅由Ericsson AB的Kenneth Lundin为2008年11月13日在斯德哥尔摩举行的Erlang用户大会编写的文档.
我想修改以前的答案.
Erlang,或者更确切地说是Erlang运行时系统(erts),默认调度程序的数量(操作系统线程)和运行队列的数量,以及平台上处理元素的数量.那是处理器核心或硬件线程.您可以使用以下命令更改这些设置:
erlang:system_flag(schedulers_online, NP) -> PrevNP
Erlang进程与任何调度程序都没有任何关联.平衡调度程序之间的过程的逻辑遵循两个规则.1)饥饿的调度程序将窃取另一个调度程序的工作.2)设置迁移路径以将具有大量进程的调度程序的进程推送到具有较少工作的调度程序.这样做是为了确保每个过程的减少计数(执行时间)的公平性.
但是,调度程序可以锁定到特定的处理元素.这不是默认情况下完成的.要让erts执行调度程序 - >核心关联使用:
erlang:system_flag(scheduler_bind_type, default_bind) -> PrevBind
其他几种绑定类型可以在文档中找到.使用亲和力可以极大地提高重载情况下的性能!特别是在高锁争用情况下.此外,linux内核至少可以说无法处理超线程.如果您的平台上有超线程,那么您应该在erlang中使用此功能.