加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Python > 正文

python – 一次添加需要多少CPU周期?

发布时间:2020-12-20 12:10:17 所属栏目:Python 来源:网络整理
导读:我想测量在 Python 3中进行加法运算所需的时钟周期数. 我写了一个程序来计算加法运算的平均值: from timeit import timeitdef test(n): for i in range(n): 1 + 1if __name__ == '__main__': times = {} for i in [2 ** n for n in range(10)]: t = timeit.
我想测量在 Python 3中进行加法运算所需的时钟周期数.

我写了一个程序来计算加法运算的平均值:

from timeit import timeit

def test(n):
    for i in range(n):
      1 + 1

if __name__ == '__main__':

    times = {}
    for i in [2 ** n for n in range(10)]:
      t = timeit.timeit("test(%d)" % i,setup="from __main__ import test",number=100000)
      times[i] = t
      print("%d additions takes %f" % (i,t))

    keys = sorted(list(times.keys()))

    for i in range(len(keys) - 2):
      print("1 addition takes %f" % ((times[keys[i+1]] - times[keys[i]]) / (keys[i+1] - keys[i])))

输出:

16 additions takes 0.288647
32 additions takes 0.422229
64 additions takes 0.712617
128 additions takes 1.275438
256 additions takes 2.415222
512 additions takes 5.050155
1024 additions takes 10.381530
2048 additions takes 21.185604
4096 additions takes 43.122559
8192 additions takes 88.323853
16384 additions takes 194.353927
1  addition takes 0.008292
1 addition takes 0.010068
1 addition takes 0.008654
1 addition takes 0.010318
1 addition takes 0.008349
1 addition takes 0.009075
1 addition takes 0.008794
1 addition takes 0.008905
1 addition takes 0.010293
1 addition takes 0.010413
1 addition takes 0.010551
1 addition takes 0.010711
1 addition takes 0.011035

因此,根据此输出,一次添加大约需要0.0095个usecs.按照this page条指令,我计算出一次加法需要25个CPU周期.这是正常值,为什么?因为汇编指令ADD只需要1-2个CPU周期.

解决方法

您正在计时函数调用(test()),for循环和对range()的调用.增加的时间根本没有.

def test(n):
    for i in range(n):
        1 + 1

import dis
dis.dis(test)

这是测试函数的字节代码(不包括对test()的调用):

2           0 SETUP_LOOP              24 (to 27)
              3 LOAD_GLOBAL              0 (range)
              6 LOAD_FAST                0 (n)
              9 CALL_FUNCTION            1
             12 GET_ITER            
        >>   13 FOR_ITER                10 (to 26)
             16 STORE_FAST               1 (i)

  3          19 LOAD_CONST               2 (2)   **** 
             22 POP_TOP             
             23 JUMP_ABSOLUTE           13
        >>   26 POP_BLOCK           
        >>   27 LOAD_CONST               0 (None)
             30 RETURN_VALUE

****注意,添加是在编译时完成的.相当多的其他语言及其编译器将会这样做,包括C.但是,标准很少定义何时实际执行11,因此它通常依赖于实现.

编辑:

你的timeit函数调用可能是这样的:

t = timeit("x += 1",setup="x = 1",number=100000)

我们可以创建一个虚函数来检查操作:

def myfunc(x):
    x += 1

import dis
dis.dis(myfunc)

做出改变会给出:

1 additions takes 0.008976
2 additions takes 0.007419
4 additions takes 0.007282
8 additions takes 0.007693
16 additions takes 0.007026
32 additions takes 0.007793
64 additions takes 0.010168
128 additions takes 0.008124
256 additions takes 0.009064
512 additions takes 0.007256
1 addition takes -0.001557
1 addition takes -0.000068
1 addition takes 0.000103
1 addition takes -0.000083
1 addition takes 0.000048
1 addition takes 0.000074
1 addition takes -0.000032
1 addition takes 0.000007

 26           0 LOAD_FAST                0 (x)
              3 LOAD_CONST               1 (1)
              6 INPLACE_ADD
              7 STORE_FAST               0 (x)
             10 LOAD_CONST               0 (None)
             13 RETURN_VALUE

注意,x = 1是INPLACE_ADD,与x = x 1不同,它是BINARY_ADD.因此,您需要确定要测量的OPCode.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读