如何使用MPI并行化Python代码?Runge-Kutta-NBody问题

2024-05-20 14:10:00 发布

您现在位置:Python中文网/ 问答频道 /正文

我正试图在python中使用MPI并行化我的python代码,迫切需要一些帮助。我真的不知道从哪里开始,我只知道我需要并行化哪个部分以使代码运行得更快

这段代码模拟了N个绕太阳运行的天体,我使用了龙格-库塔近似法,每次都将最终位置和速度保存到一个列表中,然后使用matplotlib绘制数据。我的下一步是加速这段代码,并将计算分为多个核

这里有人能帮忙吗?我真的需要一个解决方案,很高兴能补偿你的时间。 我知道我需要在代码的step_size = 3600 step_number = 36*24部分使用MPI,您可以在上面一行看到我的尝试

我想我需要得到代码来计算我的每个行星在一个核心上的位置和速度,同时在另一个核心上对另一个行星执行相同的计算,以此类推

然后我需要它把这些数据取回并“重新组合”,这样我就可以画出图表了

如果有人能伸出援手帮助我,我将万分感激


Tags: 数据代码核心列表matplotlibstep绘制解决方案
2条回答

我对这个问题的看法是,在系统的状态at和系统在t-1的状态之间存在依赖关系。你能做的最多的就是让每个核心计算单个行星或太阳的加速度和位置变化(可能可以忽略不计)。每个进程都必须将它正在处理的行星的状态发送给所有其他进程,并通过MPI从其他进程接收所有其他行星和太阳的新状态。这样做不会给你带来任何好处,因为花在交流上的时间可能会抵消并行计算中的任何好处

使用Python多处理还将导致多个进程,并在通信方面产生相同的影响。由于GIL,多线程是不可能的

这让您可以选择使用C和OpenMP来共享状态并跨线程并行化代码

另一个选项是使用Julia,它的语法与Python类似,但提供了类似于C的速度,只是JIT编译时启动时间较慢

我可能错了,如果能被纠正我会很感激,因为我很想看到一个替代方案

[编辑日期:2021年2月24日] 我知道这可能是一个学术项目。解决问题的方法如下: 您应该为每个行星/太阳启动一个进程,外加一个额外的进程,该进程将成为“控制器”。控制器将自己识别为行星/太阳+1的等级数。其他人将通过选择他们的等级作为包含行星状态的数组中的索引,并相应地选择一个行星来进行模拟。控制器将系统的状态发送给每个进程,并从每个进程返回每个行星的新状态。工作进程获得全局状态,并在一个时间步后返回其行星状态。当达到所需的时间步数时,控制器可以向所有进程发送退出消息

看到这个非常好的介绍:https://youtu.be/36nCgG40DJo

除了@Tarik's response之外,当您有许多计算/过程都可以彼此独立完成时,最好在过程之间不共享数据的情况下使用MPI。 这通常被称为“令人尴尬的平行问题”。 这是因为如果MPI进程之间的通信必须进行多次,并且进程之间不共享内存,那么MPI进程之间的通信速度会很慢

在您的情况下,您需要在每个步骤的所有流程之间进行通信。 除非每个步骤都需要很长的时间才能完成(比如说,一个小时左右),否则MPI通信造成的开销是最小的。 然而,我认为在您的情况下,每一步最多只需要几秒钟左右,在这种情况下,MPI只会使您的代码减速,而不是加速

这里您可能需要的是OpenMP,它专门用于处理进程之间的频繁通信,并且还共享内存。 然而,由于Python的工作方式,它无法实现OpenMP。 因此,如果真的需要使用并行化来加快速度,您将不得不在OpenMP中使用类似C或Julia的东西

要记住的另一件事是,Python绝对不是为效率而设计的,而是为可访问性而设计的;方便用户;和多功能性。 事实上,Python是世界上使用最慢的编程语言之一,也是目前所有流行语言中最慢的语言(例如C、C++、FORTRAN、java、Python、Ruby、JavaScript、C等)。 因此,在进行Python编程时,当效率成为优先事项时,也能够进行C编程是一个非常好的主意。 鉴于Python可以相对容易地与C代码交互,大型Python程序通常使用C语言完成高性能的操作,并为这些操作提供Python包装器/接口

相关问题 更多 >