【问题标题】:Why does `numpy.einsum` work faster with `float32` than `float16` or `uint16`? [duplicate]为什么 `numpy.einsum` 使用 `float32` 比 `float16` 或 `uint16` 工作得更快? [复制]
【发布时间】: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


【解决方案1】:

我对@9​​87654324@ 和f32 数组的测试表明,f16 对于所有计算都慢了 5-10 倍。只有在执行像数组copy 这样的字节级操作时,float16 更紧凑的性质才会显示出任何速度优势。

https://gcc.gnu.org/onlinedocs/gcc/Half-Precision.html

gcc 文档中的部分是关于半个浮点数,fp16。使用正确的处理器和正确的编译器开关,可以以加快这些计算的方式安装 numpy。我们还必须检查 numpy .h 文件是否有任何对半浮点数进行特殊处理的规定。

较早的问题,可能足以作为重复参考

Python Numpy Data Types Performance

Python numpy float16 datatype operations, and float8?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-11-03
    • 2014-03-03
    • 2020-09-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-05
    • 2015-10-06
    相关资源
    最近更新 更多