首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >基于@distributed的反斜杠矩阵反演

基于@distributed的反斜杠矩阵反演
EN

Stack Overflow用户
提问于 2022-07-12 14:50:01
回答 1查看 58关注 0票数 2

我用一个隐式格式来求解PDE,它可以在每一时间步划分成两个矩阵,然后由一个边界条件连接起来(也是在每个时间步骤)。我试图通过使用多个处理来同时反演两个矩阵来加速这个过程。

下面是一个很小(非PDE解决方案)示例中的示例。

代码语言:javascript
复制
using Distributed
using LinearAlgebra

function backslash(N, T, b, exec)
    A = zeros(N,N)
    α = 0.1
    for i in 1:N, j in 1:N
        abs(i-j)<=1 && (A[i,j]+=-α)
        i==j && (A[i,j]+=3*α+1)
    end

    A = Tridiagonal(A)
    a = zeros(N, 4, T)

    if exec == "parallel"
        for i = 1:T
            @distributed for j = 1:2
                a[:, j, i] = A\b[:, i]
            end
        end
    elseif exec == "single"
        for i = 1:T
            for j = 1:2
                a[:, j, i] = A\b[:, i]
            end
        end
    end
    return a
end

b = rand(1000, 1000)

a_single = @time backslash(1000, 1000, b, "single");
a_parallel = @time backslash(1000, 1000, b, "parallel");

a_single == a_parallel

问题来了:最后一行计算为真,速度提高了6倍,但只有2倍是可能的。我做错什么了?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-07-12 15:08:43

您正在测量的编译时间prematurely

  • Your

  • @distributed循环退出

@distributed循环不收集结果

因此,很明显,你有:

代码语言:javascript
复制
julia> addprocs(2);

julia> sum(backslash(1000, 1000, b, "single")), sum(backslash(1000, 1000, b, "parallel"))
(999810.3418359067, 0.0)

因此,为了使代码工作,您需要从分布式循环中收集数据,这些数据可以这样做:

代码语言:javascript
复制
function backslash2(N, T, b, exec)
    A = zeros(N,N)
    α = 0.1
    for i in 1:N, j in 1:N
        abs(i-j)<=1 && (A[i,j]+=-α)
        i==j && (A[i,j]+=3*α+1)
    end

    A = Tridiagonal(A)
    a = zeros(N, 4, T)

    if exec == :parallel
        for i = 1:T
           
            aj = @distributed (append!) for j = 1:2
                [A\b[:, i]]
            end
            # you could consider using SharedArrays instead
            a[:, 1, i] .= aj[1]
        a[:, 2, i] .= aj[2]
        end
    elseif exec == :single
        for i = 1:T
            for j = 1:2
                a[:, j, i] = A\b[:, i]
            end
        end
    end
    return a
end

现在你得到了同样的结果:

代码语言:javascript
复制
julia>  sum(backslash2(1000, 1000, b, :single)) == sum(backslash2(1000, 1000, b, :parallel))
true

但是,对于只需几毫秒就能执行的循环来说,分布式代码效率很低,因此在本例中,当您运行1000次@distributed代码时,执行它将花费很多倍的时间,而且每次分派分布式作业需要大约几毫秒的时间。

也许您的生产任务需要更长的时间,所以它比有意义。或者您可能会考虑使用Threads.@threads

最后但并非最不重要的是,BLAS可能被配置为多线程,并且在这个场景中,在一台机器上并行化可能没有意义(取决于场景)。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72954273

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档