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

问题描述 投票:0回答:1

为什么宽度较小的整数数组的计算速度更快?为什么 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 位整数的预期性能是 2 倍的两倍。结果是否被缓存?加速率始终大约为 4 倍、2 倍和 2 倍,所以肯定有一个原因。

x86-64 Intel i5-5250U CPU,Broadwell,具有 3MiB 的 L3 缓存。 8 GB 内存。 NumPy 1.24.3。 Python 3.11.4。 MacOS 蒙特利 12.6.7.

python numpy performance vectorization simd
1个回答
1
投票

较窄的数据类型可以加快计算速度的两个原因:

  1. 数据较少。 64 位整数数组占用的 RAM 是 16 位整数数组的四倍。即使使用复杂的处理器缓存,存储和检索数据也需要时间和电量。更多的数据位数意味着更多的时间。

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

numpy 在利用所有这些并行性方面做得很好。

© www.soinside.com 2019 - 2024. All rights reserved.