(如何)编写运行速度更快的模拟?


16

我已经开始使用python作为编程语言来执行CFD中的所有作业。我在编程方面经验很少。我来自机械工程领域,正在从事航空航天工程的高等教育。

有时,CFD的计算方面比处理方程式或进行数学运算更乏味。

有哪些一般准则可以使我们的程序运行更快?做并行处理的技巧是什么?如何编写运行速度更快的代码?

我在哪里可以得到回答上述问题的资源(对于像我这样的外行人来说很容易理解)?



@丹,我不这么认为。我要求提供“任何”可能的资源,以帮助了解新手编程策略。我没有任何特定的要求或条件。更具体地说,我要求提供有助于使代码更加美观的资源。
Subodh 2012年

您是否固定使用python或会考虑使用C ++?在这种情况下,我将建议两件事:学习C ++,找到一个开放源代码库(在我的情况下为OpenFOAM),不要从头开始开发东西,而是学习,研究高级代码,了解它的方面,更改和实验,所有这些都有特定的目的:例如您的空气动力学模拟。
tmaric 2012年

@ tomislav-maric,非常感谢。我不是严格的“ pythonian”。实际上,作为该领域的新手,我想我面前有很多选择。我也在学习OpenFOAM。因此,我同意您的观点,即应该开始从事一个项目并从中学习(或者简而言之,动手做),这正是我应该做的!谢谢。
Subodh 2012年

@smj顺便说一句,我也是机械工程专业的人,我现在是计算机科学的研究生(机械工程并没有为此做好准备)...如果您正在使用OF,请搜索C ++书籍列出堆栈溢出,然后开始学习。您需要三件事:C ++,OpenFOAM和来自计算科学的知识。通过OpenFOAM和计算科学,您可以通过树突状学习:找到任务并完成任务,根据需要进行学习。完成一些事情会激励你。至于C ++:从C ++ Primer开始学习。祝好运!:)
tmaric 2012年

Answers:


19

考虑到您专门要求使用Python,我将尝试回答您的问题。我将描述自己解决模拟问题的方法。本说明中给出了用于更快仿真的策略。

首先,我用Python制作了新的模拟原型。当然,我会尽量利用NumPySciPy。NumPy提供了适合于数值模拟的数组数据类型,而SciPy提供了适用于NumPy数组的广泛数值例程。

一旦原型工作或多或少,我将尝试了解程序或脚本的哪些部分是瓶颈。有典型的候选人:

  • Python中的循环很慢。非常慢。
  • 由于Python使用鸭子类型,所以调用函数可能很慢。

我使用一种简单的分析策略来了解所有运行时间都花在了哪里。使用IPython shell(我不能推荐足够多的东西),我使用

%timeit script.py

这个“魔术命令”将为您进行性能分析(使用timeit),并在脚本终止后向您显示带有时间的列表。使用此列表可以找出您的代码太慢的地方。

一旦确定了需要加速的部分,就可以考虑使用编译语言。我将指出两个解决方案。

首先,有Cython语言。Cython是一种非常类似于Python的编程语言(实际上,Python代码通常也是有效的Python代码);但是,Cython编译器将Cython文件转换为C代码,然后可以将其编译为可从Python使用的模块。Cython了解NumPy数组。使用Cython可以通过两种方式为您提供帮助:首先,您可以介绍数据类型。这将加速函数调用。同样,如果您遍历数组,则循环将运行得更快(实际上,如果同时输入了哑变量和数组,则会得到普通的C循环!)。其次,在我的实验中,甚至无类型脚本的运行速度也要快一些,因为它们是编译而不是解释的。

对您有用的另一种编译语言是Fortran。将Fortran与Python结合使用的方式有多种(f2pyfortwrapCython)。就我个人而言,f2py似乎是最简单的方法,我将快速描述它的作用。f2py可以将Fortran代码编译为Python模块。它将允许您将NumPy数组用作Python空间中的输入和输出变量。在Fortran空间中,这些将是普通的Fortran阵列。您可以全速运行Fortran。

就个人而言,我倾向于使用Cython,其中函数调用的数量是瓶颈。对于繁重的工作,我更喜欢f2py(也许是因为我有很强的Fortran背景)。

关于Fortran的其他说明:现代Fortran的读取和写入与NumPy非常相似-语法非常接近。这使得将NumPy代码转换为Fortran代码变得容易。

请注意,Cython和f2py都以某种方式支持并行处理。对于Cython,您将在这里找到帮助,而对于Fortran,则有诸如OpenMP或MPI之类的标准技术。此外,也有用于MPI的 P ython包装器。就个人而言,我在Python级别上使用mpi4py以及在Fortran中使用OpenMP。

让我推荐一些文献:H.-P着的《计算科学Python脚本》一书。总体而言,Langtangen是有关Python以及关于使Python更快一点的策略的重要资源。不幸的是,AFAIR没有在Cython上提及任何内容。在我作为第二篇资源时,您可能会看到这些幻灯片。这些给出了我在本文中提到的所有内容的示例(另请参见此处的代码和源代码)。互联网上还有许多其他不错的幻灯片。

如果您还有其他具体问题,我们很乐意为您提供帮助!


1
另请参见有关优化代码的scipy讲座,以获取Python分析器的概述。
丹尼斯

7

对于CFD + Python,有一个解决方案:http : //pythonflu.wikidot.com/这些是OpenFOAM之上的Python绑定(在问题注释中已经提到)。这些绑定允许在“求解器级别”上进行编程(有些示例在Python中复制了原始OpenFOAM求解器,并且它们的运行速度不比原始版本慢-另一个答案中提到的慢循环在这里不是问题,因为发生了“内部循环”在OpenFOAM的C ++代码中)。

这些绑定的优点还在于,OpenFOAM中的所有并行化都在求解器级别下进行,因此您不必为它烦恼(以及OpenFOAM核心要处理的其他内容:输入/输出,线性求解器,算子离散化)

因此,如果您只想编写一个新的求解器而又不向OF核添加新功能(边界条件,线性求解器等),那么PythonFlu可能就足够了,您可以避免使用C ++(它的学习方法比蟒蛇)

PS:本来想将此添加为对原始问题的讨论的评论,但我的声誉不允许我这样做


嗨,伯恩哈德!欢迎来到scicomp!:)
tmaric
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.