从技术上讲,为什么Erlang中的进程比OS线程更有效率?
Erlang的特点
来自Erlang编程(2009):
Erlang并发性是快速和可扩展的。 它的进程是轻量级的,因为Erlang虚拟机不会为每个创建的进程创建一个OS线程。 它们是在虚拟机中创建,调度和处理的,与底层操作系统无关。 因此,进程创建时间为微秒级别,并且不受同时存在的进程数量的影响。 将它与Java和C#进行比较,在每个进程中创建一个底层操作系统线程:您将得到一些非常有竞争力的比较结果,Erlang的性能大大优于两种语言。
来自Erlang的并发导向编程(pdf)(幻灯片)(2003):
我们观察到,创建Erlang过程所需的时间在2,500个过程中保持恒定1μs; 此后它增加到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虚拟机都必须执行调度,上下文切换以及跟踪寄存器中的值,等等......
简单来说,为什么操作系统线程不像Erlang中的进程那样执行? 他们是否需要更多支持? 为什么他们需要更大的内存占用? 为什么他们产卵和交流较慢?
从技术上讲,为什么Erlang中的进程比OS线程在产卵和通信方面更有效率? 为什么操作系统中的线程不能以同样有效的方式实现和管理? 为什么操作系统线程有更大的内存占用,加上产卵和通信速度较慢?
更多阅读
有几个促成因素:
经过一些更多的研究后,我找到了乔阿姆斯特朗的演讲。
来自Erlang - 并发世界的软件(演示)(13分钟):
[Erlang]是一种并发语言 - 我的意思是说,线程是编程语言的一部分,它们不属于操作系统。 这对于Java和C ++等编程语言来说确实是错误的。 它的线程不在编程语言中,线程是操作系统中的东西 - 并且它们继承了它们在操作系统中的所有问题。 其中一个问题是内存管理系统的粒度。 操作系统中的内存管理可以保护整个内存页面,因此线程最小的大小就是页面的最小大小。 这实际上太大了。
如果你在你的机器上增加更多的内存 - 你有相同的位数来保护内存,所以页表的粒度上升 - 你最终会使用64kB来处理你知道以几百字节运行的进程。
如果不是全部,我认为它会回答,至少我的一些问题
我在汇编器中实现了协程,并测量了性能。
在协程之间切换,也称为Erlang进程,在现代处理器上需要大约16条指令和20纳秒。 此外,您经常知道您正在切换的进程(例如:在队列中接收消息的进程可以实现为从调用进程到接收进程的直接切换),因此调度程序不会发挥作用,使得它是O(1)操作。
要切换操作系统线程,大约需要500-1000纳秒,因为您正在调用内核。 操作系统线程调度程序可能运行在O(log(n))或O(log(log(n)))时间,如果您拥有数万甚至数百万个线程,该线程将开始显着。
因此,Erlang进程速度更快,规模更好,因为切换的基本操作速度更快,调度程序运行频率更低。
链接地址: http://www.djcxy.com/p/55259.html上一篇: Technically, why are processes in Erlang more efficient than OS threads?