在 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
之前,您应该调用一次 fpar
和 nofpar
函数。
最后但同样重要的是,您的代码中没有 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
为什么在下面的 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)
包含一列实数。经过一些研究,我遇到了处理类似问题的
您的代码是正确的,但您对性能的衡量不正确。
请注意,对于此用例场景(调用外部进程),您应该可以使用绿色线程 - 根本不需要分配负载!
当第一次执行 Julia 函数时,它正在被编译。当您在多个并行进程上执行它时,所有这些进程都需要编译同一段代码。
除此之外,第一个 @distribution
宏 运行 也需要很长时间才能编译。
因此,在使用 @timed
之前,您应该调用一次 fpar
和 nofpar
函数。
最后但同样重要的是,您的代码中没有 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