首页 > 解决方案 > 了解 numpy 的循环向量化

问题描述

我想验证我是否理解了许多机器学习讲座/笔记/视频中提到的向量化代码的概念。

我对此进行了一些阅读,发现 CPU 和 GPU 有一个称为 SIMD 的指令集;单指令多数据。

例如,这可以通过将两个变量移动到两个特殊的 64/128 位寄存器,然后一次添加所有位来实现。

-Ofast例如,如果您使用标志打开优化,我也读过大多数现代编译器(例如 GCC )

-Ofast - 无视严格的标准合规性。-Ofast 启用所有 -O3 优化。它还支持并非对所有符合标准的程序都有效的优化。它打开 -ffast-math 以及 Fortran 特定的 -fno-protect-parens 和 -fstack-arrays。

然后,-Ofast应该尽可能将任何用 C/C++ 编写的循环自动矢量化为 SIMD 指令。

我在自己的代码上对此进行了测试,并且能够将 MNIST 数据集的显着加速时间从 45 分钟缩短到 5 分钟。

我也知道 numpy 是用 C 语言编写并用 PyObjects 包装的。我通读了很多他们的代码,但很难。

那么我的问题是:我的上述理解是否正确,Numpy 是否也做同样的事情,或者他们是否使用explicit pragmas或其他特殊instruction/register名称进行矢量化?

标签: pythonnumpyvectorizationsimd

解决方案


numpy 不会做那样的事情。

numpy 上下文中的术语向量化意味着您让 numpy 直接在您的数组上工作,而不是自己创建一个循环。然后通常将其传递给所谓的“通用函数”,或简称为“ufunc”。这些函数是 C 函数,它们将在 C 中的 C for 循环中处理预期的操作。

但它通常不能进行任何 ISA 矢量化。原因是这些函数对于所有类型的数组、密集或这些密集数组上的视图都是通用的。因此,由于使用的模式,您不能期望矢量化。

如果您想要 ISA 矢量化 numpy 调用,您可以使用 JIT 可以 JIT 的 numba (因此真的是 ISA 矢量化)。还有另一个项目将使用英特尔的库之一,但我再也找不到它了。


推荐阅读