58

在他们的arXiv 论文中,Julia 的原作者提到了以下内容:

2.14 Parallelism. 并行执行由标准库中的 Julia 实现的基于消息的多处理系统提供。语言设计通过提供对称协程来支持此类库的实现,也可以将其视为协作调度的线程。此功能允许将异步通信隐藏在库中,而不需要用户设置回调。Julia 目前不支持本地线程,这是一个限制,但具有避免同步使用共享内存的复杂性的优点。

他们说 Julia 不支持本机线程是什么意思?什么是原生线程?

PythonR等其他解释型语言是否支持这种类型的并行性?朱莉娅一个人在这吗?

4

1 回答 1

76

更新

2013 年问这个问题的时候,Julia 确实不支持多线程。然而,今天,Julia 支持原生线程,它已成为可组合线程编程的最佳语言模型。该模型由 Cilk 和 Intel 的 Threading Building Blocks 首创,Go 在语言层面进一步推动,现在 Julia 也使用该模型。下面关于其他动态语言的原始答案中的陈述仍然正确:它们仍然不支持本机线程并支持用户代码的并行执行。向 Julia 添加线程功能的历史在以下高级阶段取得了进展:

  • Julia 0.3:支持具有类似 OpenMP 的计算模型的本机线程(即并行 for 循环)。此功能受到高度限制:并行代码中不允许有 I/O 或网络。

  • Julia 1.3:完全可组合的高性能M:N 线程。这种线程模型与 Go(以及 Cilk 和 Intel TBB)相同,其中任务用于表达潜在的并发性,并且这些任务由调度程序在本机线程池中的线程上运行。

  • Julia 1.7:支持本地线程之间的任务迁移。这允许任务在一个本机线程上开始执行、暂停,然后在另一个线程上恢复,从而充分利用可用的计算资源。

原始答案

“本机线程”是独立的执行上下文,由操作系统内核管理,访问共享内存空间并可能在不同的内核上并发执行。将此与单独的进程进行比较,这些进程可能在多个内核上同时执行,但具有单独的内存空间。确保进程很好地交互很容易,因为它们只能通过内核相互通信。确保线程不会以不可预测的、错误的方式交互是非常困难的,因为它们可以以不受限制的方式读取和写入相同的内存。

R 的情况相当简单:R 不是多线程的。Python 稍微复杂一点:Python 确实支持线程,但由于全局解释器锁 (GIL)的原因,Python 代码无法实际并发执行。其他流行的开源动态语言在原生线程方面处于各种混合状态(Ruby:no/kinda/yes?;Node.js:no),但总的来说,答案是否定的,它们不支持完全并发的原生线程,所以 Julia 在这方面并不孤单。

当我们确实为 Julia 添加共享内存并行性时,正如我们计划的那样– 无论是使用本机线程还是使用共享内存的多个进程 – 这将是真正的并发,并且不会有 GIL 阻止同时执行 Julia 代码。然而,这是添加到语言中的一个非常棘手的功能,正如其他非常流行的成熟动态语言不存在或有限的支持所证明的那样。添加共享内存并发模型在技术上很困难,但真正的问题是设计一种编程模型,使程序员能够以高效和安全的方式有效地利用硬件并发。这个问题通常没有解决,是一个非常活跃的研究和实验领域——没有“黄金标准”可以复制。我们可以添加 POSIX 线程支持,但是这种编程模型通常被认为是危险的,并且难以正确有效地使用。Go 有一个出色的并发故事,但它是为编写高度并发的服务器而设计的,而不是为并发操作大数据而设计的,所以根本不清楚简单地复制 Go 的模型对 Julia 来说是一个好主意。

于 2013-05-07T16:01:05.487 回答