【问题标题】:How do i parallelize julia code without changing the eventual output?如何在不更改最终输出的情况下并行化 julia 代码?
【发布时间】:2018-10-26 09:44:00
【问题描述】:

我是并行计算的新手,并设法更改了我的代码,使其比我的非并行代码运行得更快,但是我的结果略有不同。我尝试使用@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

【问题讨论】:

  • 答案是肯定的。如果你能展示一个 MWE,也许有人可以提供一些帮助。
  • 如何并行化代码?我想看看你是怎么做到的。可能你错过了不止一点。朱莉娅拥有的并行计算宏并不是完全神奇的。在并行化之前仍有一些事情需要考虑(一致性和复制/访问问题)。 sleep(0.05) 是这里的瓶颈。您每次都使用sum(y),尽管您已经从之前的迭代中获得了它。请注意,我已经并行化了代码,它提供了加速,尽管不是那么重要,因为每个元素只被访问一次,这使得问题几乎都与 RAM 速度有关。

标签: parallel-processing julia


【解决方案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

【讨论】:

  • 不客气。我刚刚注意到stufftodo2前面不需要@everywhere——在主进程上定义就足够了。
猜你喜欢
  • 2021-11-09
  • 1970-01-01
  • 2018-03-18
  • 2017-07-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-18
  • 1970-01-01
相关资源
最近更新 更多