2013-08-05 2 views
3

나는 계산을 빠르게하기 위해 Cython을 배우려고 노력해왔다. 여기에 내가하려고하는 일의 하위 집합이 있습니다. 이것은 단순히 NumPy 배열을 사용하면서 재귀 수식을 사용하여 미분 방정식을 통합하는 것입니다. 나는 이미 순수한 파이썬 버전보다 100 배 빠른 속도를 달성했다. 그러나 그것은 내가 코드를 -a cython 명령에 의해 생성 된 HTML 파일을보고 기반으로 추가 속도를 얻을 수있는 것 같습니다.파이썬 오버 헤드없이 Cython에서 NumPy 배열 정의하기

%%cython 
import numpy as np 
cimport numpy as np 
cimport cython 
from libc.math cimport exp,sqrt 

@cython.boundscheck(False) 
cdef double riccati_int(double j, double w, double h, double an, double d): 
    cdef: 
     double W 
     double an1 
    W = sqrt(w**2 + d**2) 
    #dark_yellow 
    an1 = ((d - (W + w) * an) * exp(-2 * W * h/j) - d - (W - w) * an)/
      ((d * an - W + w) * exp(-2 * W * h/j) - d * an - W - w) 
    return an1 


def acalc(double j, double w): 
    cdef: 
     int xpos, i, n 
     np.ndarray[np.int_t, ndim=1] xvals 
     np.ndarray[np.double_t, ndim=1] h, a 
    xpos = 74 
    xvals = np.array([0, 8, 23, 123, 218], dtype=np.int)  #dark_yellow 
    h = np.array([1, .1, .01, .1], dtype=np.double)   #dark_yellow 
    a = np.empty(219, dtype=np.double)      #dark_yellow 
    a[0] = 1/(w + sqrt(w**2 + 1))       #light_yellow 

    for i in range(h.size):         #dark_yellow 
     for n in range(xvals[i], xvals[i + 1]):    #light_yellow 
      if n < xpos: 
       a[n+1] = riccati_int(j, w, h[i], a[n], 1.) #light_yellow 
      else: 
       a[n+1] = riccati_int(j, w, h[i], a[n], 0.) #light_yellow 
    return a 

할 수 있어야 내가 위에서 표시된 모든 9 개 라인처럼 날 것으로 보인다 : (I 개는 흰색을하고자하는 HTML 파일에 노란색이 될 줄)를 다음과 같이 내 코드는 흰색과 적절한 조정. 한 가지 문제는 NumPy 배열을 적절한 방법으로 정의하는 것입니다. 하지만 아마도 더 중요한 것은 첫 번째 레이블이 붙은 라인을 효율적으로 작동시킬 수 있다는 것입니다. 여기에서 계산의 대부분이 수행되기 때문입니다. 노란색 줄을 클릭 한 후 HTML 파일이 표시하는 생성 된 C 코드를 읽으려고했지만 솔직히이 코드를 읽는 방법을 알지 못합니다. 아무도 나를 도와 주실 수 없다면 크게 감사하겠습니다.

답변

1

루프에없는 노란색 선을 신경 쓸 필요가 없다고 생각합니다. 다음과 같은 컴파일러 지시어 빠른 루프에서 세 줄을 만들 것입니다 추가

@cython.cdivision(True) 
cdef double riccati_int(double j, double w, double h, double an, double d): 
    pass 

@cython.boundscheck(False) 
@cython.wraparound(False) 
def acalc(double j, double w): 
    pass 
+0

이지만, 즉 약 10 %를주고, 색인에 대한 파이썬 타입을 사용하는 것이 좋습니다 속도 향상, 그래서 그것은 이미 가능한 한 효율적으로 보인다. 당신의 도움을 주셔서 감사합니다! – crr

0

나는 그것이 차이가 있는지, 잘 모르겠지만, 당신은 전자 배열에 대한 사용 메모리보기를 할 수 있습니다. 지.

cdef double [:] h = np.array([1, .1, .01, .1], dtype=np.double) #dark_yellow 
cdef double [:] a = np.empty(219, dtype=np.double)    #dark_yellow 

또한 4 개의 정적 값에 대해 numpy 배열을 만드는 것은 다소 과장됩니다. 이것은 정적 C 배열로 대체 될 수 있습니다.

cdef double *h = [1, .1, .01, .1] 

그러나 루프에서 무엇이 가장 중요합니까? 라인 프로파일 러는 cython (afaik)에서 작동하지 않으므로 cProfile을 사용하는 것 외에도 함수 내에서 벤치 마크 할 time 모듈을 사용하십시오. Cython 로그에서 선 색상의 강도가 컨텍스트에서 평가되어야한다는 아이디어를 줄 수 있습니다.

as I learned

size_t i, n 
Py_ssize_t i, n 

두 번째 가장 큰 문제를 고정 cdivision 지시어를 추가 서명 된 버전

관련 문제