如何在不更改最终输出的情况下并行化julia代码?

时间:2018-10-26 09:44:00

标签: parallel-processing julia

我是并行计算的新手,并且设法以比非并行代码更快的速度运行代码,但是结果略有不同。我尝试使用@ sync,@ async,@ threads和@distributed宏,但它们似乎都无法使结果正确。

目标是找到通过迷宫的最短路径,并且在非并行运行代码时运行良好,似乎并行运行代码并不能完成搜索算法的所有迭代,从而仅给出通过迷宫的最短路径由其中一个线程/工人找到。

它的主要工作原理是从入口开始,遍历可能到达出口的所有点,然后选择到达最快点,然后重复这些步骤直到到达出口。它使用两个非嵌套的for循环来执行此操作,但是当我使用@async或@distributed之类的宏提高执行速度时,它永远找不到最短的路径。

有没有一种方法可以同时执行或并行执行,同时仍然获得相同的结果?

编辑:

我添加了一个具有相同问题的函数的示例。在通过并行化加快处理速度的同时,最终如何获得相同的z值?

    a = rand(1, 2, 15)
    function stufftodo(a)                           
        z = 0
        y = rand(size(a)[1], size(a)[2]) .* 1000
        for i in 1:size(a)[3]
            x = a[:, :, i]
            sleep(0.05)
            if sum(y)>sum(x)
                y=x
            end
        end
        z = minimum(y)
    end

1 个答案:

答案 0 :(得分:1)

在这里,任何问题都欢迎您

让我们定义此示例的可复制性数据:

using Random
Random.seed!(0)
a = rand(1, 2, 15)

我们首先测量原始功能的时序。自从Julia第一次运行@time以来,它便对我们测量的代码进行了两次编译(只有第二次测量有效):

julia> @time stufftodo(a)
  1.017913 seconds (654.90 k allocations: 33.067 MiB, 0.81% gc time)
0.042301665932029664

julia> @time stufftodo(a)
  0.772471 seconds (538 allocations: 69.813 KiB)
0.042301665932029664

现在让我们进行分发:

using Distributed
nworkers()<4 && addprocs(4)

@everywhere function stufftodo2(a)
    y = rand(size(a)[1], size(a)[2]) .* 1000
    aggfunc = (x,y) -> sum(y)>sum(x) ? x : y
    y = @distributed (aggfunc) for i in 1:size(a)[3]
        sleep(0.05)
        a[:, :, i]
    end
    minimum(y)
end

现在我们可以测量分布函数的时间了(再次,只有第二次测量有效):

julia> @time stufftodo2(a)
  2.819767 seconds (2.46 M allocations: 124.442 MiB, 1.53% gc time)
0.042301665932029664

julia> @time stufftodo2(a)
  0.206596 seconds (447 allocations: 44.609 KiB)
0.042301665932029664