【问题标题】:May I have Project Loom Clarified?我可以澄清一下 Project Loom 吗?
【发布时间】:2022-11-09 21:18:27
【问题描述】:

Brian Goetz 让我对 Loom 项目感到兴奋,为了充分理解它,我需要对现状进行一些澄清。

我的理解如下: 目前,为了有真正的并行性,我们需要每个 cpu/core 有一个线程; 1)在n核机器上拥有n+1个线程有什么意义吗? Project Loom 将通过依赖 jvm 在 JVM 内部的虚拟线程上执行任务,为我们带来几乎无限的线程/纤维。 2)这真的是平行的吗? 3)具体而言,这与上述场景“n 核机器上的 n+1 个线程”有何不同?

谢谢你的时间。

【问题讨论】:

  • n+1 通常假设一个线程会因为 IO 而停止,而另一个线程可以使用原本浪费的资源,因为 CPU 和 IO 任务都被合并了。如果将它们分开,则 m:n 可以工作,但您必须意识到并积极分开这些任务
  • Project loom 试图带来并发性,而不是并行性。并行性解决了一项任务,分布在多个线程上。并发意味着多个任务竞争相同的资源。

标签: parallel-processing project-loom


【解决方案1】:

虚拟线程允许并发(IO 限制),而不是并行(CPU 限制)。它们代表因果同时性,但不代表资源使用同时性。

事实上,如果两个虚拟线程处于 IO bound* 状态(例如等待从 REST 调用返回),则根本没有使用线程。然而,在调用完成之前,普通线程的使用(如果不使用反应式或可完成语义)将被阻塞且不可用。

* 某些情况除外(例如,使用 synchonize 与 ReentrackLock、在本机方法中发生的阻塞以及可能的其他一些次要区域)。

【讨论】:

    【解决方案2】:

    那么在 n 核机器上拥有 n+1 个线程有什么意义吗?

    一方面,大多数现代 n 核机器都有 n*2 硬件线程,因为每个内核都有 2 个硬件线程。

    有时产生比硬件线程更多的操作系统线程确实有意义。当一些操作系统线程在等待某些东西时,就是这种情况。例如,在 Linux 上,直到几年前 io_uring 出现之前,没有好的方法可以为本地磁盘上的文件实现异步 I/O。传统上,磁盘密集型应用程序产生的线程比 CPU 内核多,并且使用阻塞 I/O。

    这真的会平行吗?

    取决于实施。不仅是语言运行时,还有标准库的 I/O 相关部分。例如,在 Windows 上,当在 C# 中使用 async/await(相当于项目 loom,2012 年左右发布)进行磁盘或网络 I/O 时,这些任务是真正并行的,操作系统内核和驱动程序确实在同时做更多的工作时间。 Linux async/await 上的 AFAIK 仅对套接字而不是文件真正并行,对于异步文件 I/O,它在后台使用操作系统线程池。

    具体来说,这与上述场景“n 核机器上的 n+1 个线程”有何不同?

    由于几个原因,操作系统线程更昂贵。 (1) 它们需要本机堆栈,因此每个 OS 线程都会消耗内存 (2) 内存很慢,处理器有缓存来补偿,在 OS 线程之间切换会增加 RAM 带宽,因为在上下文切换后线程特定的数据会失效 (3) OS 调度程序正在改进几十年来,但它们仍然不是免费的。一个原因是在内存中保存/恢复线程状态需要时间。

    与切换 OS 线程相比,在 C# async/await 或 Java 的 Loom 中实现的高级协作多任务处理在切换上下文时导致的开销要小得多。至少在理论上,这应该可以提高 I/O 繁重应用程序的吞吐量和延迟。

    【讨论】:

      猜你喜欢
      • 2021-12-13
      • 2012-03-01
      • 1970-01-01
      • 2020-02-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-05-21
      • 2020-12-20
      相关资源
      最近更新 更多