【问题标题】:Parallel implementation slower than serial in Julia并行实现比 Julia 中的串行实现慢
【发布时间】:2020-06-19 23:32:17
【问题描述】:

为什么在下面的 Julia 代码中并行实现比串行慢?

using Distributed

@everywhere function ext(i::Int64)
   callmop = `awk '{ sum += $1 } END { print sum }' infile_$(i)`
   run(callmop)
end

function fpar()
   @sync @distributed for i = 1:10
      ext(i)
   end
end

function fnopar()
   for i = 1:10
      ext(i)
   end
end

val, t_par, bytes, gctime, memallocs = @timed fpar()
val, t_nopar, bytes, gctime, memallocs = @timed fnopar()

println("Parallel: $(t_par) s. Serial: $(t_nopar) s")  
# Parallel: 0.448290379 s. Serial: 0.028704802 s

文件infile_$(i) 包含一列实数。经过一些研究,我遇到了处理类似问题的postother post)。不过,如果考虑到 Julia 的开发速度,它们似乎有点过时了。有什么办法可以改善这个平行部分吗?非常感谢您。

【问题讨论】:

  • 恕我直言,这不是测试并发性的最佳示例。生成一个外部进程并同时访问同一个文件(文件/文件 IO 也有锁)同时打开了太多的蠕虫罐并掩盖了问题。此外,工作量(10 个数字)太小,多线程的开销不太可能摊销。最好将/更多数据读入一个数组,然后用它来比较单线程和多线程执行。
  • @BitTickler 感谢您的评论。上面的代码是对实际问题的简化:我绝对需要使用输入文件调用外部进程(实际上,我调用了量子化学包MOPAC)并且由于所有输入都是独立的,在我看来它是一个尴尬的平行问题。我使用了awk 命令,因为它确实与我的情况有一些相似之处。

标签: performance parallel-processing julia external-process


【解决方案1】:

您的代码是正确的,但您错误地衡量了性能。

请注意,对于这个用例场景(调用外部进程),您应该可以使用绿色线程 - 根本不需要分配负载!

当一个 Julia 函数第一次被执行时,它正在被编译。当您在几个并行进程上执行它时,它们都需要编译同一段代码。

最重要的是,第一个@distribution 宏运行也需要很长时间来编译。 因此,在使用 @timed 之前,您应该调用一次 fparnofpar 函数。

最后但同样重要的是,您的代码中没有 addprocs,但我假设您已使用 -p Julia 选项将工作进程添加到您的 Julia 主进程。顺便说一句,你没有提到你有多少个工作进程。

我通常这样测试代码:

@time fpar()
@time fpar()
@time fnopar()
@time fnopar()

第一个措施是了解编译时间,第二个措施是了解运行时间。

还值得一看 BenchmarkTools 包和 @btime 宏。

关于性能测试@distributed 有很大的通信开销。在某些情况下,这可以通过使用SharedArrays 在其他情况下通过使用Thread.@threads 来缓解。但是,在您的情况下,最快的代码将是使用绿色线程的代码:

function ffast()
   @sync for i = 1:10
      @async ext(i)
   end
end

【讨论】:

  • 非常感谢您的快速回答,非常有趣的评论。事实上,我使用-p 标志来设置进程数。那么你有什么建议可以在这里更好地测试性能?
  • 你是绝对正确的,如果排除编译时间,并行实现会更快。但是,我会说,使用 8 个进程的性能改进是相当离散的。并行 0.014887 秒与串行 0.031449 秒。如果考虑到间接费用,我认为这是尽可能好的?
  • 分布式性能有很多问题,例如沟通时间很昂贵。用绿色线程试试我的代码提案,告诉我你得到了什么:-)
  • 结果:Parallel: 0.010793981 s. Serial: 0.031697373 s. Green: 0.007791053。绿色线程是最好的解决方案。非常感谢:)
猜你喜欢
  • 1970-01-01
  • 2012-09-11
  • 2013-10-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-15
  • 2013-12-20
  • 2016-01-29
相关资源
最近更新 更多