加速Cython中的数值集成

smo*_*loy 1 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
Run Code Online (Sandbox Code Playgroud)

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

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

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

谢谢阅读.

Vee*_*rac 5

蒂姆Pietzcker是正确的,它更适合代码审查,但它也几乎在这里的主题,所以我会去做.

如果你跑

cython -a myfile.pyx
Run Code Online (Sandbox Code Playgroud)

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

运用

from libc.math cimport cos
Run Code Online (Sandbox Code Playgroud)

会让你使用C cos,这会更快.

还有一些检查除以零和分裂的符号.通过将编译器指令 cdivision转换为可以避免这些True.

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

另请注意,使用numba和使用autojit纯Python代码可能会更好甚至更好.numba做疯了.