Erlang BEAM 机器的减少

Mar*_*ger 5 concurrency erlang multithreading scheduling vm-implementation

Erlang是一种众所周知的编程语言,因其轻量级线程而闻名(除其他外)。Erlang 通常是用BEAM 机器实现的。Erlang BEAM 机器的描述 (H'97) 说

为了保证公平调度,一个进程在经过固定数量的减少后被挂起,然后从队列中恢复第一个进程。

我对这种减少的概念很感兴趣。根据 (H'97),只有以下 BEAM 命令算作减少:

  • C/CO/ResC : 调用本地/常驻 Erlang 函数
  • CL:丢弃当前堆栈帧。调用本地 Erlang 函数。
  • CEx/TrCEx:调用外部 Erlang 函数(跟踪或其他方式)。
  • CExL/TrCExL:丢弃当前堆栈帧并调用外部 Erlang 函数(跟踪或其他方式)。
  • M_C_r:加载参数寄存器 x(0)。调用常驻 Erlang 函数。
  • M_CL_r:加载参数寄存器 x(0)。丢弃当前堆栈帧。调用本地 Erlang 函数。

所有这些都涉及函数调用。相比之下,调用 C 函数(例如TrC/TrCO)和调用内置函数(例如由Bif_0_ 调用)不算作减少。

问题。在这个序言之后,这是我想知道的。

  1. 为什么减少用于线程之间的调度,而不是时间片?
  2. 为什么只有上述命令使减少计数器前进?
  3. (H'97) 中的描述有点过时了,当代 Erlang 如何处理调度?

(H'97) B. Hausman,Erlang BEAM 虚拟机规范

Luk*_*kas 6

我会尽力回答你的问题。

1)不使用时间片的主要原因是性能和可移植性。从操作系统读取单调时间值是相当昂贵的,如果我们必须为每个函数调用执行此操作,则开销会变得相当大。不同操作系统的成本也有很大差异。然而,减少计数机制只要求机器擅长减少整数,而大多数机器都是如此。

2)他们没有。正如你所说,该清单已经非常过时了。从那以后,虚拟机的大部分工作方式都被重写了。作为一般经验法则;函数调用(不是返回)或任何可能花费未知时间的事情都会减少计数。这包括 bifs、nifs、gc、发送/接收消息以及可能更多我现在想不到的内容。

3)调度和抢占是非常不同的事情。您可能想看看我几年前举办的关于如何安排日程的网络研讨会:https://www.youtube.com/watch? v=tBAM_N9qPno