加速Cython中的数值集成

时间:2014-09-22 07:59:36

标签: python performance cython

作为物理计算的一部分,我从csv文件加载一个电场值列表,并将它们传递给Cython函数进行集成。这不是文件中值的简单求和,但需要在集成的每个步骤重新计算某个参数。通过重新组织代码,并将最慢的部分移动到Cython,我已经实现了速度的显着提升,但我怀疑还有进一步的优化可以做到。

这是我想加速的Cython功能:

import numpy as np
cimport numpy as np
DTYPE = np.float
ctypedef np.float_t DTYPE_t
cdef float m = 938272046
cdef float c = 299792458
cimport cython

@cython.boundscheck(False)
def ELTintegration(float xelmax, float deltaT, float phi, float omega, 
                np.ndarray[DTYPE_t] zExtract, np.ndarray[DTYPE_t] EzExtract, float KEin):
    cdef float integ = 0 
    cdef float xelmax_deltaT = xelmax * deltaT
    cdef unsigned int i, loopLen=len(EzExtract)
    cdef float v
    cdef float z, Ez, phaseTerm, diff
    cdef float newE, gamma, beta
    for i in range(len(EzExtract)):
        z = zExtract[i]
        Ez = EzExtract[i]
        newE = KEin + integ
        gamma = newE/m + 1 
        beta = (1 - 1/gamma**2)**0.5
        v = beta * c 
        phaseTerm = np.cos(omega*z/v + phi)
        diff = phaseTerm * Ez * xelmax_deltaT
        integ = integ + diff

    return integ

每个ndarray都是一维的,包含~4000个浮点数。

正如你所看到的,我已经声明了我使用的所有变量,关闭了边界检查,使数组索引有效,并将所有必要的计算从循环中拉出来。

我是否达到了我可以合理地加速的极限?在实现更高效的功能方面,我有什么遗漏?认为我可以用另一个因子来加速这个因素是否现实?

感谢阅读。

1 个答案:

答案 0 :(得分:5)

Tim Pietzcker是对的,它更适合Code Review,但它在这里几乎也是主题,所以我会选择它。

如果你跑

cython -a myfile.pyx

你会看到黄色。通常,但并非总是如此,黄色意味着缓慢。最重要的黄色是np.cos电话。这将是非常缓慢的,因为您正在通过Python并进行大量的类型创建来完成它。

使用

from libc.math cimport cos

将允许您使用C {#1}},这将更快。

还有一些检查除以零和分裂的符号。将compiler directive cos转为cdivision可以避免这些问题。

请注意,使用Numpy数组的现代方法是使用memoryview语法(例如。True用于类型DTYPE_t[:]的1D内存视图。)

另请注意,在普通Python代码上使用DTYPE_tnumba可能会更好甚至更好。 autojit会做出疯狂的事情。