c语言会自动生成simd,从Cython-cod生成SIMD指令

代码中有两个问题(使用选项-a使其可见):numpy数组的索引不是efficient

您在^{中忘记了int

考虑到这一点,我们得到:cpdef int f(np.ndarray[np.int_t] f): ##HERE

assert f.dtype == np.int

cdef int array_length = f.shape[0]

cdef int sum = 0 ##HERE

cdef int k

for k in range(array_length):

sum += f[k]

return sum

对于循环,以下代码:

^{pr2}$

}

这并不是那么糟糕,但是对于优化器来说并不像人类编写的普通代码那么容易。正如您已经指出的那样,__pyx_pybuffernd_f.diminfo[0].strides在编译时是未知的,这会阻止向量化。在

但是,当使用typed memory views时,您将获得更好的结果,即:cpdef int mf(int[::1] f):

cdef int array_length = len(f)

...

这使得C代码更加不透明,至少我的编译器可以更好地优化:__pyx_t_2 = __pyx_v_array_length;

for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_2; __pyx_t_3+=1) {

__pyx_v_k = __pyx_t_3;

__pyx_t_4 = __pyx_v_k;

__pyx_v_sum = (__pyx_v_sum + (*((int *) ( /* dim=0 */ ((char *) (((int *) __pyx_v_f.data) + __pyx_t_4)) ))));

}

这里最关键的一点是,我们要让cython明白,内存是连续的,即int[::1]与{}相比是连续的,对于numpy数组,必须考虑一个可能的stride!=1。在

在本例中,cython生成的C代码的结果是same assembleras the code我本应编写的。正如crisb所指出的,添加-march=native将导致向量化,但在这种情况下,这两个函数的汇编器将再次略有不同。在

然而,根据我的经验,编译器在优化由cython创建的循环时经常会遇到一些问题,并且/或者更容易遗漏一个细节,这会妨碍生成真正优秀的C代码。所以我处理horse循环的策略是用纯C语言编写它们,并使用cython来包装/访问它们——通常这会更快一些,因为我们还可以为这个被截取的代码使用专用的编译器标志,而不会影响整个cython模块。在

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值