Краткий ответ: отключить проверку границ в функции c_dCov
, добавив следующий декоратор в строку прямо перед ней:
cimport cython
@cython.boundscheck(False) # Deactivate bounds checking
def c_dCov(double[:, :] a, double[:, :] b, int n):
Кроме того, вы можете добавить директиву компилятора в начало вашего кода. Сразу после вашей магической линии Cython вы должны поставить:
%%cython -a
#cython: language_level=3, boundscheck=False
Если у вас есть файл setup.py
, вы также можете отключить глобальную проверку границ:
from distutils.core import setup
from Cython.Build import cythonize
setup(
name="foo",
ext_modules=cythonize('foo.pyx', compiler_directives={'boundscheck': False}),
)
Независимо от того, как это было сделано, отключения проверки границ само по себе было достаточно, чтобы получить следующий отчет по оптимизации:
![enter image description here](https://i.stack.imgur.com/v21v4.png)
Некоторые другие оптимизации, предлагаемые документами Cython , отключают индексацию с отрицательными числами и заявляют, что ваши массивы гарантированно будут иметь непрерывный макет в памяти. С учетом всех этих оптимизаций подпись c_dCov
станет:
cimport cython
@cython.boundscheck(False) # Deactivate bounds checking
@cython.wraparound(False) # Deactivate negative indexing.
def c_dCov(double[:, ::1] a, double[:, ::1] b, int n):
, но только @cython.boundscheck(False)
было необходимо для получения лучшего отчета по оптимизации.
Теперь, когда я посмотрю поближе, хотя у вас нет этих оптимизаций в вашем фрагменте кода, у вас есть декораторы boundscheck(False)
и wraparound(False)
в коде в вашем отчете по оптимизации. Вы уже пробовали те, и они не работали? Какую версию Cython вы используете? Может быть, вам нужно обновление.
Объяснение
Каждый раз, когда вы обращаетесь к массиву по индексу, происходит проверка границ. Это связано с тем, что когда у вас есть массив arr
формы (5,5)
и вы пытаетесь получить доступ к arr[19,27]
, ваша программа выдаст ошибку вместо того, чтобы позволить вам получить доступ за пределами данных. Однако, ради скорости, некоторые языки не выполняют проверку границ доступа к массиву (например, C / C ++). Cython позволяет при желании отключить проверку границ для оптимизации производительности. В Cython вы можете либо отключить глобальную проверку границ для всей программы с помощью директивы компилятора boundscheck
, либо для отдельной функции с декоратором @cython.boundscheck(False)
.