热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Cython:为什么size_t比int快?-Cython:whyissize_tfasterthanint?

ChangingcertainCythonvariablesfromtypeinttotypesize_tcansignificantlyreducesomefunctio

Changing certain Cython variables from type int to type size_t can significantly reduce some functions times (~30%), but I do not understand why.

将某些Cython变量从int类型更改为type_t类型可以显着减少一些函数时间(~30%),但我不明白为什么。

For example:

例如:

cimport numpy as cnp
import numpy as np

def sum_int(cnp.int64_t[::1] A):
    cdef unsigned long s = 0
    cdef int k
    for k in xrange(A.shape[0]):
        s += A[k]
    return s

def sum_size_t(cnp.int64_t[::1] A):
    cdef unsigned long s = 0
    cdef size_t k
    for k in xrange(A.shape[0]):
        s += A[k]
    return s

a = np.array(range(1000000))

And the timing results:

时间结果如下:

In [17]: %timeit sum_int(a)   
1000 loops, best of 3: 652 µs per loop

In [18]: %timeit sum_size_t(a)
1000 loops, best of 3: 427 µs per loop

I am new to Cython, and know Fortran better than C. Help me out. What is the important difference between these two variable types that causes such a performance difference? What is it that I don't grok about Cython?

我是Cython的新手,比C.更了解Fortran。帮助我。这两种变量类型之间的重要区别是什么导致了这种性能差异?什么是我不喜欢Cython?

2 个解决方案

#1


9  

You'd likely have to do a line by line profiling to find out exactly, but one thing stands out to me from the produced C file: int version is checked for wraparound to negative numbers, size_t is assumed ok.

你可能不得不进行逐行分析以找出确切的结果,但是有一件事从我生成的C文件中脱颖而出:检查int版本是否为环绕负数,size_t假定为ok。

In the int loop: (t_3 is assigned from k, they're the same type)

在int循环中:(t_3从k分配,它们是相同的类型)

if (__pyx_t_3 <0) {
  __pyx_t_3 += __pyx_v_A.shape[0];
  if (unlikely(__pyx_t_3 <0)) __pyx_t_4 = 0;
} else if (unlikely(__pyx_t_3 >= __pyx_v_A.shape[0])) __pyx_t_4 = 0;

In the size_t loop:

在size_t循环中:

if (unlikely(__pyx_t_3 >= (size_t)__pyx_v_A.shape[0])) __pyx_t_4 = 0;

So no wraparound test is needed because size_t is unsigned and guaranteed not to wrap around when indexing items in memory. The rest is virtually the same.

因此,不需要进行环绕测试,因为size_t是无符号的,并且保证在索引内存中的项目时不会回滚。其余几乎是一样的。

Update: regarding your unsigned int results - what's your size of int and size_t? Any chance they're different size, causing the change? In my case the C code for uint and size_t is identical. (since size_t is unsigned and specifically unsigned int on this system)

更新:关于你的unsigned int结果 - 你的int和size_t的大小是多少?他们有什么不同的规模,导致变化?在我的例子中,uint和size_t的C代码是相同的。 (因为size_t是无符号的,在此系统上特别是unsigned int)

#2


3  

On a 64 bit system there seem to be two reasons:

在64位系统上,似乎有两个原因:

  1. Use an unsigned integer for the loop:

    对循环使用无符号整数:

    %%cython
    
    cimport numpy as cnp
    import numpy as np
    
    def sum_int_unsigned(cnp.int64_t[::1] A):
        cdef unsigned long s = 0
        cdef unsigned k
        for k in xrange(A.shape[0]):
            s += A[k]
        return s
    
  2. Use a long instead of an int:

    使用long而不是int:

    %%cython
    
    cimport numpy as cnp
    import numpy as np
    
    def sum_int_unsigned_long(cnp.int64_t[::1] A):
        cdef unsigned long s = 0
        cdef unsigned long k
        for k in xrange(A.shape[0]):
            s += A[k]
        return s
    

Timings:

时序:

%timeit sum_int(a)
1000 loops, best of 3: 1.52 ms per loop

%timeit sum_size_t(a)
1000 loops, best of 3: 671 µs per loop

Using unsigned brings us half way:

使用unsigned将我们带到了一半:

%timeit sum_int_unsigned(a) 
1000 loops, best of 3: 1.09 ms per loop

Using long accounts for the rest:

使用长帐户来完成剩下的工作:

%timeit sum_int_unsigned_long(a)
1000 loops, best of 3: 648 µs per loop

推荐阅读
  • C++字符字符串处理及字符集编码方案
    本文介绍了C++中字符字符串处理的问题,并详细解释了字符集编码方案,包括UNICODE、Windows apps采用的UTF-16编码、ASCII、SBCS和DBCS编码方案。同时说明了ANSI C标准和Windows中的字符/字符串数据类型实现。文章还提到了在编译时需要定义UNICODE宏以支持unicode编码,否则将使用windows code page编译。最后,给出了相关的头文件和数据类型定义。 ... [详细]
  • IjustinheritedsomewebpageswhichusesMooTools.IneverusedMooTools.NowIneedtoaddsomef ... [详细]
  • 本文介绍了PHP常量的定义和使用方法,包括常量的命名规则、大小写敏感性、全局范围和标量数据的限制。同时还提到了应尽量避免定义resource常量,并给出了使用define()函数定义常量的示例。 ... [详细]
  • des算法php,Des算法属于加密技术中的
    本文目录一览:1、des是什么算法2、80分求 ... [详细]
  • NN,NearestNeighbor,最近邻KNN,K-NearestNeighbor,K最近邻KNN分类的思路:分类的过程其实是直接将测试集的每一个图片和训练集中的所有图片进行比 ... [详细]
  • SayIhaveabytearraywith100,000bytesinit.Iwanttoconverteachbyteintoitstextualrepre ... [详细]
  • 前面一直讲到使用CreateThread来创建线程,那么这章告诉你应该使用_beginthreadex()取代CreateThread()。一、使用_beginthr ... [详细]
  • 本文讨论了如何优化解决hdu 1003 java题目的动态规划方法,通过分析加法规则和最大和的性质,提出了一种优化的思路。具体方法是,当从1加到n为负时,即sum(1,n)sum(n,s),可以继续加法计算。同时,还考虑了两种特殊情况:都是负数的情况和有0的情况。最后,通过使用Scanner类来获取输入数据。 ... [详细]
  • 本文介绍了使用Spark实现低配版高斯朴素贝叶斯模型的原因和原理。随着数据量的增大,单机上运行高斯朴素贝叶斯模型会变得很慢,因此考虑使用Spark来加速运行。然而,Spark的MLlib并没有实现高斯朴素贝叶斯模型,因此需要自己动手实现。文章还介绍了朴素贝叶斯的原理和公式,并对具有多个特征和类别的模型进行了讨论。最后,作者总结了实现低配版高斯朴素贝叶斯模型的步骤。 ... [详细]
  • 本文介绍了贝叶斯垃圾邮件分类的机器学习代码,代码来源于https://www.cnblogs.com/huangyc/p/10327209.html,并对代码进行了简介。朴素贝叶斯分类器训练函数包括求p(Ci)和基于词汇表的p(w|Ci)。 ... [详细]
  • 本文介绍了Foundation框架中一些常用的结构体和类,包括表示范围作用的NSRange结构体的创建方式,处理几何图形的数据类型NSPoint和NSSize,以及由点和大小复合而成的矩形数据类型NSRect。同时还介绍了创建这些数据类型的方法,以及字符串类NSString的使用方法。 ... [详细]
  • 本文介绍了利用ARMA模型对平稳非白噪声序列进行建模的步骤及代码实现。首先对观察值序列进行样本自相关系数和样本偏自相关系数的计算,然后根据这些系数的性质选择适当的ARMA模型进行拟合,并估计模型中的位置参数。接着进行模型的有效性检验,如果不通过则重新选择模型再拟合,如果通过则进行模型优化。最后利用拟合模型预测序列的未来走势。文章还介绍了绘制时序图、平稳性检验、白噪声检验、确定ARMA阶数和预测未来走势的代码实现。 ... [详细]
  • http:blog.sina.com.cnsblog_491529d60100061h.html安装完SLED10后发现仍然有“热启动网络不通”的问题,原因是内核版本 ... [详细]
  • IntheBestPracticestoimprovewebsitePerformancehttp:developer.yahoo.comperformancerules.h ... [详细]
  • 路径查找基础知识-动画演示
    这是教程教你建立路径查找算法的第一步。路径查找就是在两点之间查找最短路径的算法,你可以在很多地方应用,例如:玩家控制角色时通过点击设置目的地时,就需要用到。在开始前,我们需要明确一点:路径查找是在终点 ... [详细]
author-avatar
WenFJ
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有