首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >并行化代码(DifferentialEquations.jl) -朱莉娅

并行化代码(DifferentialEquations.jl) -朱莉娅
EN

Stack Overflow用户
提问于 2021-09-29 14:14:40
回答 2查看 260关注 0票数 2

我有以下耦合的PDE系统(来自于离散积分微分PDE):

习是我控制的x网格上的点。我可以用以下简单的代码来解决这个问题:

代码语言:javascript
复制
using DifferentialEquations

function ode_syst(du,u,p, t)
    N = Int64(p[1])
    beta= p[2]
    deltax = 1/(N+1)
    xs = [deltax*i for i in 1:N]
    for j in 1:N
        du[j] = -xs[j]^(beta)*u[j]+deltax*sum([u[i]*xs[i]^(beta) for i in 1:N])
    end
end

N = 1000
u0 = ones(N)
beta = 2.0
p = [N, beta]
tspan = (0.0, 10^3);

prob = ODEProblem(ode_syst,u0,tspan,p);
sol = solve(prob);

然而,随着网格的细化,即增加N,计算时间迅速增长(我猜在N中是二次定标)。对于如何使用分布式并行或多线程来实现这一点,有什么建议吗?

附加信息:--我附加了可能有助于理解程序大部分时间花费在何处的剖析图

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-09-29 18:52:29

我查看了您的代码,发现了一些问题,例如由于重新计算和项而意外引入了O(N^2)行为。

我的改进版本使用Tullio包来进一步提高矢量化的速度。Tullio也有可调参数,如果系统变得足够大,就可以进行多线程处理。在这里查看可以调优在“选项”部分的哪些参数。您可能还会看到GPU支持在那里,我没有测试,但它可能会产生进一步的速度或崩溃。我也选择从穴位阵列得到长度,这应该使使用更经济,更容易出错。

代码语言:javascript
复制
using Tullio

function ode_syst_t(du,u,p, t)
    N = length(du)
    beta = p[1]
    deltax = 1/(N+1)
    @tullio s := deltax*(u[i]*(i*deltax)^(beta))
    @tullio du[j] = -(j*deltax)^(beta)*u[j] + s
    return nothing
end

你的代码:

代码语言:javascript
复制
 @btime sol = solve(prob);
  80.592 s (1349001 allocations: 10.22 GiB)

我的代码:

代码语言:javascript
复制
prob2 = ODEProblem(ode_syst_t,u0,tspan,[2.0]);
@btime sol2 = solve(prob2);
  1.171 s (696 allocations: 18.50 MiB)

结果大致一致:

代码语言:javascript
复制
julia> sum(abs2, sol2(1000.0) .- sol(1000.0))
1.079046922815598e-14

Lutz Lehmanns解决方案-我也设定了基准:

代码语言:javascript
复制
prob3 = ODEProblem(ode_syst_lehm,u0,tspan,p);

@btime sol3 = solve(prob3);
  1.338 s (3348 allocations: 39.38 MiB)

然而,当我们用tspan (0.0,10.0)来标度N到1000000时,

代码语言:javascript
复制
prob2 = ODEProblem(ode_syst_t,u0,tspan,[2.0]);

@time solve(prob2);
  2.429239 seconds (280 allocations: 869.768 MiB, 13.60% gc time)

prob3 = ODEProblem(ode_syst_lehm,u0,tspan,p);

@time solve(prob3);
  5.961889 seconds (580 allocations: 1.967 GiB, 11.08% gc time)

由于在我的旧机器和生锈机器中使用了两个核,我的代码变得比以前快了一倍多。

票数 4
EN

Stack Overflow用户

发布于 2021-09-29 18:43:00

分析公式。显然,原子术语重复。所以它们只能计算一次。

代码语言:javascript
复制
function ode_syst(du,u,p, t)
    N = Int64(p[1])
    beta= p[2]
    deltax = 1/(N+1)
    xs = [deltax*i for i in 1:N]
    term = [ xs[i]^(beta)*u[i] for i in 1:N]
    term_sum = deltax*sum(term)
    for j in 1:N
        du[j] = -term[j]+term_sum
    end
end

这应该只会线性地增加N

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

https://stackoverflow.com/questions/69378110

复制
相关文章

相似问题

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