numpy 为什么向量化计算在较小宽度的整数类型上更快?

jslywgbw  于 12个月前  发布在  其他
关注(0)|答案(1)|浏览(68)

为什么在较小宽度的整数数组上的计算更快?为什么8位整数数组的计算速度比16位整数数组快4倍,而16位整数数组的计算速度只比32位整数数组快2倍?32位整数数组的计算也只比64位整数数组快2倍:

import numpy as np

np.random.seed(200)
arr_int8 = np.array(np.random.randint(10, size=int(1e8)), dtype=np.int8)

np.random.seed(200)
arr_int16 = np.array(np.random.randint(10, size=int(1e8)), dtype=np.int16)

np.random.seed(200)
arr_int32 = np.array(np.random.randint(10, size=int(1e8)), dtype=np.int32)

np.random.seed(200)
arr_int64 = np.array(np.random.randint(10, size=int(1e8)), dtype=np.int64)

%%timeit
arr_int8_mult = arr_int8*7
# 28.5 ms ± 4.14 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

%%timeit
arr_int16_mult = arr_int16*7
# 124 ms ± 2.11 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

%%timeit
arr_int32_mult = arr_int32*7
# 250 ms ± 2.96 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

%%timeit
arr_int64_mult = arr_int64*7
# 533 ms ± 29.9 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

有一次我得到了arr_int8_mult
最慢的运行时间是最快的运行时间的5.97倍。这可能意味着正在缓存中间结果。
为什么从32位到16位会有加速,而从16位到8位会有更大的加速?我猜更多的更小宽度的整数可以打包到一个固定宽度的寄存器中,但这并不能解释为什么8位整数的预期性能是2x的两倍。是否缓存结果?加速大约是4x,2x和2x一致,所以一定有原因。
x86-64 Intel i5-5250U CPU,Broadwell,3 MiB三级缓存。8 GB RAM。NumPy 1.24.3. Python 3.11.4. MacOS Monterey 12.6.7.

puruo6ea

puruo6ea1#

两个原因更窄的数据类型使计算更快:
1.更少的数据。64位整数数组占用的RAM是16位整数数组的四倍。即使使用精心设计的处理器缓存,存储和检索数据也需要时间和功率。更多数据意味着更多时间。

  1. SIMD并行化:单指令多数据操作允许现代处理器执行多个简单操作,如“将一堆数字乘以7”或“取两个长数字向量的内积”。处理器为更宽的数据类型提供更少的并行同时操作。而且,8位数据是一种特殊的高度优化的情况,因为它在显示操作中的重要性。
    numpy在利用所有这些并行性方面做得很好。

相关问题