是什么让绑定CPU的任务的绿色线程变慢



我最近在一个论坛上看到一些评论,说绿色线程可能很便宜,但不适合CPU绑定的并发任务。他们以Go为例,指出为CPU绑定任务使用goroutines明显比使用原始线程(操作系统级线程(的C/Java/Rust等效程序慢

我知道绿色线程在IO绑定任务的效率方面非常好。但我不知道它们对于CPU受限的任务来说并不是那么好。这是真的吗?如果是,为什么?

绿色线程的优点是避免了在(典型(线程切换时切换到内核的开销。同样,创建绿色线程的成本(通常(较小。因此,如果您的工作负载涉及大量的线程创建和/或切换,那么绿色线程可能是的优势。

但另一方面,对于纯绿色线程1,线程都共享一个内核。执行从一个线程切换到另一个线程,但一次实际上只运行一个线程。为了获得真正的并行性(并利用多个核心(,您需要常规线程或常规线程和绿色线程的混合。

此外,典型的绿色线程实现不允许绿色线程被抢占。(在使用空间中这样做既复杂又昂贵。(因此,线程切换只发生在线程自愿切换的点上;例如,当等待信号或锁定、执行异步I/O操作等时。

与您所理解的相反,纯绿色线程不适合阻塞I/O。当一个绿色线程对内核进行阻塞I/O系统调用时,没有办法重新调度到另一个绿色螺纹。因此,您需要一个使用空间库,它将使用选择器或其他方法将绿色线程的阻塞I/O请求映射到异步I/O请求上。这增加了复杂性和性能开销。

当然。。。pro和con将取决于实际线程设计和实现的细节,以及它们如何与操作系统交互。这使得很难一概而论。


1-在这个答案的上下文中,我将其视为定义。如果操作系统可以为一个进程分配多个核心,那么根据定义操作系统需要知道线程。。。而且它们不是纯绿色的

因为绿色线程不是真正并行运行的,而是轮流运行的。并行性是通过异步I/O实现的。这很像在单个CPU上进行协作多任务处理。

异步I/O是非阻塞的。当您调用时,它会立即返回,并在完成时发出回调函数的信号。这样,您可以在等待I/O完成的同时做其他事情。绿色线程使用此功能,并运行其他等待的"线程";绿色丝线";同时等待该I/O操作完成。

由于绿色线程只能在I/O操作期间切换任务,因此CPU绑定操作基本上将阻塞其他绿色线程。

那么,为什么绿色线程比普通线程更好呢?因为它们是精简的,所以在主要用于I/O绑定任务的情况下,比常规线程可扩展得多。它们当然不适合CPU受限的任务。

在CPU受限的情况下,绿色线程相当于在单个处理器上进行协作多任务处理。协同多任务处理要求一个任务自愿放弃计算,给另一个任务cpu时间。这种上下文切换导致L1/2/3缓存抖动,这比串行完成任务的替代方案慢。

同样在单核机器上,OS级线程的速度与"线程"一样慢;绿色";CPU绑定任务上的线程。

最新更新