高性能的Python扩展(1)

简介

通常来说,Python不是一种高性能的语言,在某种意义上,这种说法是真的。但是,随着以Numpy为中心的数学和科学软件包的生态圈的发展,达到合理的性能不会太困难。

当性能成为问题时,运行时间通常由几个函数决定。用C重写这些函数,通常能极大的提升性能。

在本系列的第一部分中,我们来看看如何使用NumPy的C API来编写C语言的Python扩展,以改善模型的性能。在以后的文章中,我们将在这里提出我们的解决方案,以进一步提升其性能。

文件

这篇文章中所涉及的文件可以在Github上获得。

模拟

作为这个练习的起点,我们将在像重力的力的作用下为N体来考虑二维N体的模拟。

以下是将用于存储我们世界的状态,以及一些临时变量的类。

在开始模拟时,N体被随机分配质量m,位置r和速度v。对于每个时间步长,接下来的计算有:

  1. 合力F,每个体上的合力根据所有其他体的计算。
  2. 速度v,由于力的作用每个体的速度被改变。
  3. 位置R,由于速度每个体的位置被改变。

第一步是计算合力F,这将是我们的瓶颈。由于世界上存在的其他物体,单一物体上的力是所有作用力的总和。这导致复杂度为O(N^2)。速度v和位置r更新的复杂度都是O(N)。

如果你有兴趣,这篇维基百科的文章介绍了一些可以加快力的计算的近似方法。

纯Python

在纯Python中,使用NumPy数组是时间演变函数的一种实现方式,它为优化提供了一个起点,并涉及测试其他实现方式。

合力计算的复杂度为O(N^2)的现象被NumPy的数组符号所掩盖。每个数组操作遍历数组元素。

可视化

这里是7个物体从随机初始状态开始演化的路径图:

State Machine Diagram

性能

为了实现这个基准,我们在项目目录下创建了一个脚本,包含如下内容:

我们使用cProfile模块来测试衡量这个脚本。

前几行告诉我们,compute_F确实是我们的瓶颈,它占了超过99%的运行时间。

在Intel i5台式机上有101体,这种实现能够通过每秒257个时间步长演化世界。

简单的C扩展 1

在本节中,我们将看到一个C扩展模块实现演化的功能。当看完这一节时,这可能帮助我们获得一个C文件的副本。文件src/simple1.c,可以在GitHub上获得。

关于NumPy的C API的其他文档,请参阅NumPy的参考。Python的C API的详细文档在这里

样板

文件中的第一件事情是先声明演化函数。这将直接用于下面的方法列表。

接下来是方法列表。

这是为扩展模块的一个导出方法列表。这只有一个名为evolve方法。

样板的最后一部分是模块的初始化。

另外,正如这里显示,initsimple1中的名称必须与Py_InitModule中的第一个参数匹配。对每个使用NumPy API的扩展而言,调用import_array是有必要的。

数组访问宏

数组访问的宏可以在数组中被用来正确地索引,无论数组被如何重塑或分片。这些宏也使用如下的代码使它们有更高的可读性。

在这里,我们看到访问宏的一维和二维数组。具有更高维度的数组可以以类似的方式被访问。

在这些宏的帮助下,我们可以使用下面的代码循环r:

命名标记

上面定义的宏,只在匹配NumPy的数组对象定义了正确的名称时才有效。在上面的代码中,数组被命名为py_mpy_r。为了在不同的方法中使用相同的宏,NumPy数组的名称需要保持一致。

计算力

特别是与上面五行的Python代码相比,计算力数组的方法显得颇为繁琐。

请注意,我们使用牛顿第三定律(成对出现的力大小相等且方向相反)来降低内环范围。不幸的是,它的复杂度仍然为O(N^2)。

演化函数

该文件中的最后一个函数是导出的演化方法。

在这里,我们看到了Python参数如何被解析。在该函数底部的时间步长循环中,我们看到的速度和位置向量的x和y分量的显式计算。

性能

C版本的演化方法比Python版本更快,这应该不足为奇。在上面提到的相同的i5台式机中,C实现的演化方法能够实现每秒17972个时间步长。相比Python实现,这方面有70倍的提升。

观察

注意,C代码一直保持尽可能的简单。输入参数和输出矩阵可以进行类型检查,并分配一个Python装饰器函数。删除分配,不仅能加快处理,而且消除了由Python对象不正确的引用计数造成的内存泄露(或更糟)。

下一部分

在本系列文章的下一部分,我们将通过发挥C-相邻NumPy矩阵的优势来提升这种实现的性能。之后,我们来看看使用英特尔的SIMD指令和OpenMP来进一步推进。

如果您有任何疑问,意见,建议或更正,请通过联系链接告诉我。

5 收藏 1 评论

关于作者:Janzou

做一直倦懒的小猫咪,享受午后阳光(新浪微博:@Jan_zou) 个人主页 · 我的文章 · 13

相关文章

可能感兴趣的话题



直接登录
最新评论
跳到底部
返回顶部