pan*_*ein 6 parallel-processing performance external-process julia
为什么在下面的 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
Run Code Online (Sandbox Code Playgroud)
这些文件infile_$(i)包含一列实数。经过一些研究,我遇到了处理类似问题的这篇文章和另一篇文章)。不过,如果考虑到 Julia 的开发速度,它们似乎有点过时了。有没有办法改进这个平行部分?非常感谢您提前。
您的代码是正确的,但您错误地衡量了性能。
请注意,对于此用例场景(调用外部进程),您应该可以使用绿色线程 - 根本不需要分配负载!
当 Julia 函数第一次执行时,它正在被编译。当您在多个并行进程上执行它时,所有这些进程都需要编译同一段代码。
最重要的是,第一个@distribution宏运行也需要很长时间来编译。因此,在使用之前,@timed您应该同时调用fpar和nofpar函数。
最后但并非最不重要的是addprocs,您的代码中没有,但我假设您已使用-pJulia 选项将工作进程添加到您的 Julia 主进程。顺便说一句,您没有提到您拥有多少个工作进程。
我通常这样测试代码:
@time fpar()
@time fpar()
@time fnopar()
@time fnopar()
Run Code Online (Sandbox Code Playgroud)
第一个措施是了解编译时间,第二个措施是了解运行时间。
也值得一看BenchmarkTools包和@btime宏。
关于性能测试@distributed具有显着的通信开销。在某些情况下,这可以通过SharedArrays在其他情况下使用Thread.@threads. 但是,在您的情况下,最快的代码是使用绿色线程的代码:
function ffast()
@sync for i = 1:10
@async ext(i)
end
end
Run Code Online (Sandbox Code Playgroud)