Я пытаюсь оптимизировать двойной цикл для интегратора N-тела, и я обнаружил, что проблема с моим кодом заключается в том, что у меня возникают огромные накладные расходы, когда я записываю сохраненные переменные в области просмотра памяти.
Первоначально этот код был векторизован в виде numpy, но он вызывался внутри другого цикла for для обновления позиций частиц, и накладные расходы были жестокими.У меня есть вектор позиций NX2 np.ndarray (X), и я хочу вернуть вектор импульсов Nx2 (XOut) - текущий код, указанный ниже, возвращает представление памяти, но это нормально, потому что я хотел бы в конечном итоге встроить этофункция в другой функции Cython, как только я отладил это узкое место.
Я попробовал команду cython -a "name.pyx" и обнаружил, что у меня более или менее все есть как C-тип.Однако я обнаружил, что в нижней части цикла запись в представление памяти XOut [ii, 0] - = valuex влечет за собой большую часть времени выполнения.Если я изменю это на константу, так что XOut [ii, 0] - = 5, код будет примерно в 40 раз быстрее.Я думаю, это означает, что я делаю какую-то операцию копирования в этой строке, которая замедляет меня.Мои фоны Cython / C ++ являются элементарными, но я думаю, что мне нужно изменить синтаксис так, чтобы я записывал в память представление из указателя.Любой совет будет очень признателен;Спасибо!
import numpy as np
cimport numpy as np
from cython.view cimport array as cvarray
cimport cython
from libc.math cimport sinh, cosh, sin, cos, acos, exp, sqrt, fabs, M_PI
DTYPE = np.float64
ctypedef np.float64_t DTYPE_t
cdef DTYPE_t pi = 3.141592653589793
@cython.cdivision(True)
@cython.boundscheck(False) # turn off bounds-checking for entire function
@cython.wraparound(False) # turn off negative index wrapping for entire function
def intTerms(const DTYPE_t[:,:] X, DTYPE_t epsilon, DTYPE_t[:,:] XOut):
cdef Py_ssize_t ii,jj,N
N = X.shape[0]
cdef DTYPE_t valuex,valuey,r2,xvec,yvec
for ii in range(0,N):
for jj in range(ii+1,N):
xvec = X[ii,0]-X[jj,0]
yvec = X[ii,1]-X[jj,1]
r2 = max(xvec**2+yvec**2,epsilon)
valuex = xvec/r2**2
valuey = yvec/r2**2
XOut[ii,0] -= valuex
XOut[ii,1] -= 5 #valuey
XOut[jj,0] += 5 #valuex
XOut[jj,1] += 5 #valuey
XOut[ii,0] /= 2*pi
XOut[ii,1] /= 2*pi
return XOut