【发布时间】:2015-02-18 19:39:42
【问题描述】:
考虑以下 iPython 性能测试,我们在其中创建一对 10,000 长的 32 位向量并将它们相加。先用整数运算,再用浮点运算:
from numpy.random import randint
from numpy import int32, float32
a, b = randint(255,size=10000).astype(int32), randint(255,size=10000).astype(int32)
%timeit a+b # int32 addition, gives 20.6µs per loop
a, b = randint(255,size=10000).astype(float32), randint(255,size=10000).astype(float32)
%timeit a+b # float32 addition, gives 3.91µs per loop
为什么浮点版本快 5 倍?
如果您使用 float64 进行相同的测试,则所需时间是 float32 的两倍,如果我们充分利用硬件,这是您所期望的。然而,对于int8 到int64,整数情况的时间似乎是恒定的。这一点,再加上 5 倍的减速,让我怀疑它完全无法使用 SSE。
对于int32,当a+b 被a & 0xff 或a >> 2 替换时,我观察到类似的20µs 值,这表明问题不仅限于加法。
我正在使用numpy 1.9.1,但不幸的是我不记得我是在本地编译它还是下载了二进制文件。但无论哪种方式,这种性能观察对我来说都是非常令人震惊的。我的版本怎么可能在整数运算方面如此无望?
编辑: 我还在一台类似但独立的 PC 上进行了测试,运行 numpy 1.8,我很确定它直接来自 PythonXY 二进制文件。我得到了同样的结果。
问题:其他人是否看到类似的结果,如果没有,我该怎么做才能像他们一样?
【问题讨论】:
-
您可以使用
np.show_config()和import numpy.distutils.system_info as sysinfo; sysinfo.show_all()收集有关如何编译numpy 的信息。见this SO question。 -
@unutbu - 我刚刚运行了
sysinfo.show_all()- 请参阅output on pastebin - 它主要是“不可用”的列表。 -
您的观察是正确的:在撰写本文时,只有布尔运算和浮点运算使用 SIMD。这是通过显式内在函数调用完成的,因此它应该很少依赖于编译设置。与任何其他开源项目一样,我们始终欢迎贡献...
-
@Jaime - 你在说这个文件吗:
numpy/numpy/core/src/umath/simd.inc.src。我不声称对它在做什么有任何想法,但令我惊讶的是,一旦程序员处理了所有广播/步进逻辑,编译器就没有机会自动矢量化循环。是否存在我可以表现出兴趣的现有问题/里程碑。如果没有,您是否会考虑创建一个...我看不到自己在短期内破解 numpy 的核心。
标签: python performance numpy vectorization sse