@spawn fetch 和 @sync 朱莉娅中的 @sync 有什么区别

lon*_*000 3 multithreading julia

异步完成多项工作(主要是排序向量和函数计算(其中计算是计算或内存限制的,目前,我可以通过以下方式编写这些操作:

  1. 使用Threads.@spawn
_f1 = Threads.@spawn f1(x)
_f2 = Threads.@spawn f2(x)
_f3 = Threads.@spawn f3(x)
y1 = fetch(_f1)
y2 = fetch(_f2)
y3 = fetch(_f3)
Run Code Online (Sandbox Code Playgroud)

还有这种模式(看起来更干净):

@sync begin
  @async y1 = f1(x)
  @async y2 = f2(x)
  @async y3 = f3(x)
end
Run Code Online (Sandbox Code Playgroud)

对于这个特定的用例,哪一个是首选?

Prz*_*fel 5

Julia 对并行化有以下支持(另请参阅https://docs.julialang.org/en/v1/manual/parallel-computing/

  1. 使用@simd@inbounds宏生成 SIMD 汇编代码(有关更多详细信息,请阅读https://docs.julialang.org/en/v1/base/simd-types/ )

  2. 绿色线程(协同例程)——这些不是实际的线程,但允许一个任务等待另一个任务,通常其他任务不会消耗当前线程上的 CPU。很好的例子包括等待密集的 I/O 操作或分布式进程的编排。绿色线程非常轻,可以有数千个,但它们都在单个(调用)系统线程中执行。

  3. 通过模块的线程Threads。这允许生成实际的系统线程。优点(与此列表中的下一个方案相比)是所有线程共享相同的进程内存。

  4. 通过模块进行多处理/分布式计算Distributed。这里的好处是您可以使用相同的 API 从单台机器转移到集群。在任何 HPC 计算场景中,这是首先要考虑的选择

  5. GPU计算

在您的帖子中,您正在考虑绿色线程与真实线程。规则很简单:

  • 如果您的函数f1, f2,f3主要执行 I/O 并且不是 CPU 密集型(例如从互联网下载文件)或等待其他进程完成 - 使用绿色线程 ( @sync/ @async)
  • 否则使用Threads(或Distributed计算)。这对于 CPU 密集型作业尤其重要,其中绿色线程不会给您带来任何性能提升,因为它们使用单​​个系统线程。