2014-09-22 4 views
1

В рамках вычисления физики я загружаю список значений электрического поля из файла csv и передаю их функции Cython для интеграции. Это не просто суммирование значений в файле, но требует пересчета определенного параметра на каждом этапе интеграции. Реорганизуя код и перемещая самые медленные части в 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 

Каждый из ndarrays одномерно и содержит ~ 4000 поплавки.

Как вы можете видеть, я объявил все переменные, которые я использую, отключил проверку границ, сделал эффективную индексацию массива и вытащил все необходимые вычисления из цикла.

Я достиг предела того, что я могу разумно сделать, чтобы ускорить это? Есть ли что-то, что я упустил с точки зрения достижения более эффективной функции? Является ли реалистичным думать, что я мог бы ускорить это еще на 2%?

Спасибо за чтение.

+2

Я думаю, что это может быть лучше подходит для http://codereview.stackexchange.com, так как ваш код работает, и вы просите способы его улучшить. StackOverflow больше настроен на исправление ошибок/получение программы для запуска вообще. –

+0

Вы пробовали запустить проект в PyPy? Это особенно хорошо подходит для подобных алгоритмических вещей, которые вы делаете. – haael

+0

Спасибо за рекомендацию PyPy. Я посмотрю на это. На данный момент (после использования предложений Veedrac) я оптимизировал код так же, как и сейчас, но PyPy может быть хорошим инструментом для будущих проектов. Благодаря! – smolloy

ответ

5

Tim Pietzcker прав, что он лучше подходит для Code Review, но это также почти по теме, поэтому я поеду за ним.

Если запустить

cython -a myfile.pyx 

Вы увидите желтый. Часто, но не всегда, желтый означает медленный. Самый важный желтый цвет - с вызовом np.cos. Это будет очень медленно, потому что вы проходите через Python и делаете много типов, чтобы сделать это.

Использование

from libc.math cimport cos 

позволит использовать Кассиопеяне cos, который будет намного быстрее.

Есть также некоторые проверки деления на ноль и знак деления. Этого можно избежать, повернув compiler directivecdivision до True.

Обратите внимание, что современный способ использования массивов Numpy - с синтаксисом memoryview (например, DTYPE_t[:] для 1D-памяти типа DTYPE_t).

Также обратите внимание, что вы можете быть как можно лучше или лучше, используя numba и autojit на простом коде Python. numba делает сумасшедшие вещи.

+0

Ничего себе. Я получил порядок от использования косинуса libc! Невероятный. Теперь узкие места производительности в других частях моего проекта являются реальной проблемой, и я думаю, что эта функция также оптимизирована по мере необходимости. Большое спасибо за вашу помощь, и спасибо за то, что я должен был использовать Code Review. – smolloy

+0

Я попытался поднять ответ, но не получил достаточных очков репутации. Но я принял это как ответ, который мне нужен. – smolloy

Смежные вопросы