【发布时间】:2017-10-21 13:51:04
【问题描述】:
在我使用 numpy 1.12.0 的基准测试中,使用 float32 ndarrays 计算点积比其他数据类型快得多:
In [3]: f16 = np.random.random((500000, 128)).astype('float16')
In [4]: f32 = np.random.random((500000, 128)).astype('float32')
In [5]: uint = np.random.randint(1, 60000, (500000, 128)).astype('uint16')
In [7]: %timeit np.einsum('ij,ij->i', f16, f16)
1 loop, best of 3: 320 ms per loop
In [8]: %timeit np.einsum('ij,ij->i', f32, f32)
The slowest run took 4.88 times longer than the fastest. This could mean that an intermediate result is being cached.
10 loops, best of 3: 19 ms per loop
In [9]: %timeit np.einsum('ij,ij->i', uint, uint)
10 loops, best of 3: 43.5 ms per loop
我尝试分析 einsum,但它只是将所有计算委托给 C 函数,所以我不知道造成这种性能差异的主要原因是什么。
【问题讨论】:
-
它很可能已经编译为使用浮点数 32 和 64,而不是更小的浮点数。现代操作系统和处理器都是 64 位的。
-
我认为这也与 numpy 必须模仿
float16的事实有关。见here -
@romeric 但是
uint16也往往比较慢,这是为什么呢? -
我现在能想到的一个用例:如果我有一个不需要
float32精度的数据集,如果uint16一样快,我可以将内存消耗减少一半。 -
这里可能存在不止一个问题。请注意,
einsum在后台使用了一些显式的 SIMD 内在函数。 FPU 通常要快得多,而您正在做的 (double contraction) 是Fused Multiply-Add (FMA)的精确应用。整数没有FMA,一般来说,整数运算无法实现那么多的持续吞吐量。但问题可能出在其他地方。
标签: python numpy numpy-einsum