在 Julia 中,并行实现比串行实现慢

Parallel implementation slower than serial in Julia

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

using Distributed

@everywhere function ext(i::Int64)
   callmop = `awk '{ sum +=  } 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) 包含一列实数。经过一些研究,我遇到了处理类似问题的 and this )。不过,如果考虑到 Julia 的开发速度,它们似乎有点过时了。有什么办法可以改进这个并行部分吗?非常感谢您。

您的代码是正确的,但您对性能的衡量不正确。

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

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

除此之外,第一个 @distribution 宏 运行 也需要很长时间才能编译。 因此,在使用 @timed 之前,您应该调用一次 fparnofpar 函数。

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

我通常这样测试代码:

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

第一步是了解编译时间,第二步是了解运行ning时间。

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

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

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