Julia 并行性:@distributed (+) 比串行慢?

Adr*_*ian 3 parallel-processing julia

在互联网上看了几个关于 Julia 并行性的教程后,我决定实现一个小的并行片段来计算谐波级数。

序列号为:

harmonic = function (n::Int64)
    x = 0
    for i in n:-1:1 # summing backwards to avoid rounding errors
        x +=1/i
    end
    x
end
Run Code Online (Sandbox Code Playgroud)

我制作了 2 个并行版本,一个使用@distributed宏,另一个使用@everywhere宏(julia -p 2顺便说一句):

@everywhere harmonic_ever = function (n::Int64)
    x = 0
    for i in n:-1:1
        x +=1/i
    end
    x
end

harmonic_distr = function (n::Int64)
    x = @distributed (+) for i in n:-1:1
        x = 1/i
    end
    x
end
Run Code Online (Sandbox Code Playgroud)

但是,当我运行上面的代码和@time它时,我没有得到任何加速 - 事实上,该@distributed版本运行速度明显变慢!

@time harmonic(10^10)
>>> 53.960678 seconds (29.10 k allocations: 1.553 MiB) 23.60306659488827
job = @spawn harmonic_ever(10^10)
@time fetch(job)
>>> 46.729251 seconds (309.01 k allocations: 15.737 MiB) 23.60306659488827
@time harmonic_distr(10^10)
>>> 143.105701 seconds (1.25 M allocations: 63.564 MiB, 0.04% gc time) 23.603066594889185
Run Code Online (Sandbox Code Playgroud)

完全和绝对让我感到困惑的是“ 0.04% gc time”。我显然遗漏了一些东西,而且我看到的示例不是 1.0.1 版本(例如 used @parallel)。

crs*_*nbr 6

你的分布式版本应该是

function harmonic_distr2(n::Int64)
    x = @distributed (+) for i in n:-1:1
        1/i # no x assignment here
    end
    x
end
Run Code Online (Sandbox Code Playgroud)

@distributed循环将累积值1/i在每一个工人都那么最后的主进程。

请注意,使用BenchmarkTools@btime宏而不是基准测试通常也更好@time

julia> using Distributed; addprocs(4);

julia> @btime harmonic(1_000_000_000); # serial
  1.601 s (1 allocation: 16 bytes)

julia> @btime harmonic_distr2(1_000_000_000); # parallel
  754.058 ms (399 allocations: 36.63 KiB)

julia> @btime harmonic_distr(1_000_000_000); # your old parallel version
  4.289 s (411 allocations: 37.13 KiB)
Run Code Online (Sandbox Code Playgroud)

如果只在一个进程上运行,并行版本当然会更慢:

julia> rmprocs(workers())
Task (done) @0x0000000006fb73d0

julia> nprocs()
1

julia> @btime harmonic_distr2(1_000_000_000); # (not really) parallel
  1.879 s (34 allocations: 2.00 KiB)
Run Code Online (Sandbox Code Playgroud)