@spawn fetch和@sync @async在Julia中有什么区别?

3

要异步地执行多项工作(主要是排序向量和函数计算,其中计算受制于计算或内存,目前我可以按以下方式编写这些操作:

  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)

还有一种更简洁的模式:

@sync begin
  @async y1 = f1(x)
  @async y2 = f2(x)
  @async y3 = f3(x)
end

针对这种特定的使用情况,哪一个更受推荐?

你也可以在 Threads.@spawn 中使用 @sync - fredrikekre
1个回答

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)。 - 否则,请使用线程(或分布式计算)。这在CPU密集型作业的情况下尤其重要,因为绿色线程将无法提供任何性能提升,因为它们利用单个系统线程。

应该写一本关于“使用Julia进行并行编程”的书。我会购买它;-) - Antonello
这里有几篇我关于并行计算的帖子 - 如果你都找到了,那基本上就是所有需要知道的了;-) - Przemyslaw Szufel
@PrzemyslawSzufel Threads模块是否真的会生成操作系统线程?就我所知,“@spawn”与“@async”几乎相同,只是它可以在任何可用的线程上进行调度,并且您必须手动等待它。 - hasrthur
当使用-t参数或设置了JULIA_NUM_THREADS系统环境变量时,线程实际上是“生成”(=分配)的。然而,@async使用的是绿色线程,这与Threads提供的操作系统级线程完全不同。所有绿色线程都将在单个系统线程中运行,因此它们只对I/O阻塞操作有意义。另一方面,Threads可用于诸如并行计算之类的事情(在这种情况下,@async不会提供任何优势)。 - Przemyslaw Szufel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接