作为物理计算的一部分,我从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个浮点数。
正如你所看到的,我已经声明了我使用的所有变量,关闭了边界检查,使数组索引有效,并将所有必要的计算从循环中拉出来。
我是否达到了我可以合理地加速的极限?在实现更高效的功能方面,我有什么遗漏?认为我可以用另一个因子来加速这个因素是否现实?
感谢阅读。
答案 0 :(得分:5)
如果你跑
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_t
和numba
可能会更好甚至更好。 autojit
会做出疯狂的事情。