小编典典

从技术上讲,为什么 Erlang 中的进程比 OS 线程更高效?

all

Erlang的特点

来自Erlang 编程(2009
年):

Erlang 并发是快速且可扩展的。它的进程是轻量级的,因为 Erlang 虚拟机不会为每个创建的进程创建一个 OS 线程。它们在 VM
中创建、调度和处理,独立于底层操作系统。因此,进程创建时间是微秒级的,并且与同时存在的进程数无关。将此与 Java 和 C#
进行比较,后者为每个进程创建一个底层操作系统线程:您将获得一些非常有竞争力的比较,Erlang 大大优于这两种语言。

来自Erlang
中的面向并发编程(pdf)

(幻灯片)(2003):

我们观察到创建一个 Erlang 进程所花费的时间是恒定的 1μs 到 2,500 个进程;此后,它增加到大约 3μs,最多可进行 30,000
次处理。Java 和 C# 的性能显示在图的顶部。对于少数过程,创建一个过程大约需要 300μs。创建超过两千个进程是不可能的。

我们看到,对于多达 30,000 个进程,在两个 Erlang 进程之间发送消息的时间约为 0.8μs。对于 C#,每条消息大约需要
50μs,直到最大进程数(大约 1800 个进程)。Java 更糟糕的是,对于多达 100 个进程,每条消息大约需要 50μs,此后当有大约 1000
个 Java 进程时,它迅速增加到每条消息 10ms。

我的想法

从技术上讲,我不完全理解为什么 Erlang 进程在生成新进程方面效率更高,并且每个进程的内存占用要小得多。操作系统和 Erlang VM
都必须进行调度、上下文切换以及跟踪寄存器中的值等等......

简而言之,为什么操作系统线程的实现方式与 Erlang
中的进程不同?他们是否必须支持更多的东西?为什么他们需要更大的内存占用?为什么它们的产卵和交流速度较慢?

从技术上讲,为什么 Erlang 中的进程在生成和通信方面比 OS
线程更有效?为什么不能以同样有效的方式实现和管理操作系统中的线程?为什么操作系统线程有更大的内存占用,加上更慢的生成和通信?

更多阅读


阅读 92

收藏
2022-07-28

共1个答案

小编典典

有几个促成因素:

  1. Erlang 进程不是操作系统进程。它们由 Erlang VM 使用轻量级协作线程模型(在 Erlang 级别抢先,但在协作调度的运行时控制下)实现。这意味着切换上下文要便宜得多,因为它们只在已知的受控点切换,因此不必保存整个 CPU 状态(正常、SSE 和 FPU 寄存器、地址空间映射等)。
  2. Erlang 进程使用动态分配的堆栈,堆栈开始时非常小,并根据需要增长。这允许在不占用所有可用 RAM 的情况下生成数千甚至数百万的 Erlang 进程。
  3. Erlang 曾经是单线程的,这意味着不需要确保进程之间的线程安全。它现在支持 SMP,但同一调度器/核心上的 Erlang 进程之间的交互仍然非常轻量级(每个核心有单独的运行队列)。
2022-07-28