Рассмотрим следующий минимальный пример:Cython boundscheck = True быстрее, чем boundscheck = False
#cython: language_level=3, boundscheck=False, wraparound=False, initializedcheck=False, cdivision=True
cimport cython
from libc.stdlib cimport malloc
def main(size_t ni, size_t nt, size_t nx):
cdef:
size_t i, j, t, x, y
double[:, :, ::1] a = <double[:ni, :ni, :nx]>malloc(ni * ni * nx * sizeof(double))
double[:, :, ::1] b = <double[:nt, :ni, :nx]>malloc(nt * ni * nx * sizeof(double))
size_t[:, :, ::1] best = <size_t[:nt, :ni, :nx]>malloc(nt * ni * nx * sizeof(size_t))
size_t mxi
double s, mxs
for t in range(nt):
for j in range(ni):
for y in range(nx): # this loops does nothing but is needed for the effect below.
mxs = -1e300
for i in range(ni):
for x in range(nx):
with cython.boundscheck(False): # Faster!?!?
s = b[t, i, x] + a[i, j, x]
if s >= mxs:
mxs = s
mxi = i
best[t + 1, j, y] = mxi
return best[0, 0, 0]
по существу суммированием двух 2D массивов вдоль некоторых конкретных осей и найти индекс Максимизация вдоль другой оси.
При компиляции с помощью gcc -O3 и вызываемых с аргументами (1, 2000, 2000) добавление boundscheck = True приводит к выполнению в два раза быстрее, чем при boundscheck = False.
Любой намек на то, почему это так? (Ну, я, наверное, думаю, что это опять-таки связано с GOV autovectorization ...)
Заранее спасибо.
(кросс отправленный от Cython пользователей)
В моих тестах, версия с 'с cython.boundscheck (True) 'примерно в 3 раза медленнее. Я думаю, что память для 'a',' b', 'best' неинициализирована из-за' malloc'. Я изменил это на эквивалентный вызов calloc. Кроме того, строка 'best [t + 1, j, y]', кажется, индексирует недопустимую память, когда 't == nt - 1'. –
Изменение mallocs на callocs и замену 't + 1' на' t' не меняет (меняет) результаты. У моего 'setup.py' есть' extra_compile_args = ["- O3"] ', и я использую gcc 5.1.0. – antony
ОК, я пробовал с -O3, и с обеих версий получаю ту же скорость. Я использую gcc 4.9.1. Если посмотреть на сгенерированный код C, я думаю, что возможно, что gcc достаточно умен, чтобы знать, что проверки дополнительных границ никогда не будут инициированы (из-за условия цикла for). Я не знаю, почему вы получаете такие разные скорости. –