当我写信给" a"时,我所要做的简化代码要慢得多。阵列:
pyx文件中的:
import cython
import numpy as np
cimport numpy as np
ctypedef np.float64_t DTYPE_t
@cython.boundscheck(False)
@cython.wraparound(False)
@cython.nonecheck(False)
def writearray(np.ndarray[DTYPE_t, ndim=1] a):
cdef int i,j,k,l
cdef DTYPE_t sum=0.0
for i in range(100):
for j in range(100):
for k in range(100):
for l in range(1000):
sum+=1.0
a[0]+=sum #this is the trouble line that makes the code slow.
我以为我有" a [0]"和"总和"是同一类型,但我呢? 在调用此函数之前," a"数组声明为
a=np.zeros(5, dtype=np.float64)
分析" a [0] + =总和"使用" cython -a"显示(没有黄色):
__pyx_t_5 = 0;
*__Pyx_BufPtrStrided1d(__pyx_t_11kobpairwise_DTYPE_t *,
__pyx_pybuffernd_a.rcbuffer->pybuffer.buf, __pyx_t_5,
__pyx_pybuffernd_a.diminfo[0].strides) += __pyx_v_sum;
提前致谢。
这个问题比a的索引取决于所有i,j,k,l和sum不再增加常数的完整问题简化得多,所以我需要找出这个的根本原因问题而不是将[0]移出循环等等。
答案 0 :(得分:0)
你说a [0] + = sum是使代码变慢的麻烦线。你是怎么决定的?关于它有多快或多慢的宝贵信息很少。是否需要比你评论时长10%或1000%?
鉴于您所谈论的真实情况涉及许多其他变量,这些变量将索引确定为a,我怀疑它根本不在缓存中并且必须被取出每一次。其他一切都很快,因为它是可预测的(线性地逐步遍历数组),但如果a足够大(数千个条目)并且你随机索引它,那么它可能不适合缓存以及其他所有事情。
所以不是[0] + =总和很慢。那很快。数学肯定很快。可预测的指数也很快。
[random_index]加载速度慢,因为它不在缓存中,因为当前random_index和最后一个random_index之间的差异通常很大,所以CPU的一切都是通常会隐藏一些或大部分延迟,让你陷入困境。