【问题标题】:Julia significantly slower with @parallelJulia 使用 @parallel 显着变慢
【发布时间】:2016-05-01 13:32:42
【问题描述】:

我有这个代码(原始热传递):

function heat(first, second, m)
    @sync @parallel for d = 2:m - 1
        for c = 2:m - 1
            @inbounds second[c,d] = (first[c,d] + first[c+1, d] + first[c-1, d] + first[c, d+1] + first[c, d-1]) / 5.0;
        end
    end
end

m = parse(Int,ARGS[1]) #size of matrix
firstm = SharedArray(Float64, (m,m))
secondm = SharedArray(Float64, (m,m))

for c = 1:m
    for d = 1:m
        if c == m || d == 1
            firstm[c,d] = 100.0
            secondm[c,d] = 100.0
        else
            firstm[c,d] = 0.0
            secondm[c,d] = 0.0
        end
    end
end
@time for i = 0:opak
    heat(firstm, secondm, m)
    firstm, secondm = secondm, firstm
end

此代码在顺序运行时提供了很好的时间,但是当我添加 @parallel 时,即使我在一个线程上运行它也会减慢速度。我只需要解释为什么会这样?仅在不改变热函数算法的情况下编写代码。

【问题讨论】:

  • 我不确定并行更新/读取共享数组的不同元素是否真的有效。
  • @RezaAfzalan 如果SharedArray 中的每个参与进程仅适用于其数组的本地索引,它应该可以正常工作。 OP 是否查看了并行计算文档中的advection example?我发现它很有帮助。注意localindices划分的边界。
  • 与并行计算无关,但早期形成的一个有益习惯:在 Julia 中,按列而不是按行填充 firstmsecondm 效率更高。尝试将d 索引放在外循环中,将c 变量放在内循环中。

标签: julia


【解决方案1】:

看看http://docs.julialang.org/en/release-0.4/manual/performance-tips/ 。与建议相反,您大量使用全局变量。它们被认为可以随时更改类型,因此每次引用它们时都必须对其进行装箱和拆箱。这个问题Julia pi aproximation slow 也有同样的问题。为了使您的函数更快,将全局变量作为函数的输入参数。

【讨论】:

  • 它解决了我的 pi 近似问题,但函数参数中都有变量。正如我所说,这运行顺利,但只有没有@parallel。对不起,我忘了给热添加迭代(它应该切换那些矩阵)。已编辑
  • 我认为@sync 是不必要的,没有它我有改进。这些循环不依赖于先前的循环,所以忽略它。
  • 删除@sync 后它不会返回正确答案。也出现了警告。警告:强行打断忙碌的工作人员警告:无法终止所有工作人员
【解决方案2】:

有几点需要考虑。其中之一是m 的大小。如果它很小,并行性会带来很大的开销而不会带来很大的收益:

julia 36967257.jl 4
# Parallel:
0.040434 seconds (4.44 k allocations: 241.606 KB)
# Normal:
0.042141 seconds (29.13 k allocations: 1.308 MB)

对于更大的m,您可以获得更好的结果:

julia 36967257.jl 4000
# Parallel:
0.054848 seconds (4.46 k allocations: 241.935 KB)
# Normal:
3.779843 seconds (29.13 k allocations: 1.308 MB)

加两句:

1/ 初始化可以简化为:

for c = 1:m, d = 1:m
    if c == m || d == 1
        firstm[c,d] = 100.0
        secondm[c,d] = 100.0
    else
        firstm[c,d] = 0.0
        secondm[c,d] = 0.0
    end
end

2/ 您的有限差分模式看起来不稳定。请查看Linear multistep method 或 ADI/Crank Nicolson。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-09-06
    • 1970-01-01
    • 1970-01-01
    • 2022-01-27
    • 2023-01-20
    • 1970-01-01
    • 1970-01-01
    • 2017-03-14
    相关资源
    最近更新 更多