猿问

Numpy 性能差异取决于数值

在评估 Numpy 中的表达式时,我发现了一个奇怪的性能差异。


我执行了以下代码:


import numpy as np

myarr = np.random.uniform(-1,1,[1100,1100])

然后


%timeit np.exp( - 0.5 * (myarr / 0.001)**2 )

>> 184 ms ± 301 µs per loop (mean ± std. dev. of 7 runs, 1 loop each)


%timeit np.exp( - 0.5 * (myarr / 0.1)**2 )

>> 12.3 ms ± 34.3 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

在第二种情况下,计算速度快了近 15 倍!请注意,唯一的区别是因子为 0.1 或 0.001。


这种行为的原因是什么?我可以更改某些内容以使第一次计算与第二次计算一样快吗?


UYOU
浏览 153回答 2
2回答

ABOUTYOU

使用英特尔 SVML我没有numexpr使用英特尔 SVML,但numexpr使用 SVML 应该和 Numba 一样好。该Numba基准测试表明无SVML完全一样的行为,但SVML更好的表现。代码import numpy as npimport numba as nbmyarr = np.random.uniform(-1,1,[1100,1100])@nb.njit(error_model="numpy",parallel=True)def func(arr,div):  return np.exp( - 0.5 * (myarr / div)**2 )时间安排#Core i7 4771#Windows 7 x64#Anaconda Python 3.5.5#Numba 0.41 (compilation overhead excluded)func(myarr,0.1)                      -> 3.6msfunc(myarr,0.001)                    -> 3.8ms#Numba (set NUMBA_DISABLE_INTEL_SVML=1), parallel=Truefunc(myarr,0.1)                      -> 5.19msfunc(myarr,0.001)                    -> 12.0ms#Numba (set NUMBA_DISABLE_INTEL_SVML=1), parallel=Falsefunc(myarr,0.1)                      -> 16.7msfunc(myarr,0.001)                    -> 63.2ms#Numpy (1.13.3), set OMP_NUM_THREADS=4np.exp( - 0.5 * (myarr / 0.001)**2 ) -> 70.82msnp.exp( - 0.5 * (myarr / 0.1)**2 )   -> 12.58ms#Numpy (1.13.3), set OMP_NUM_THREADS=1np.exp( - 0.5 * (myarr / 0.001)**2 ) -> 189.4msnp.exp( - 0.5 * (myarr / 0.1)**2 )   -> 17.4ms#Numexpr (2.6.8), no SVML, parallelne.evaluate("exp( - 0.5 * (myarr / 0.001)**2 )") ->17.2msne.evaluate("exp( - 0.5 * (myarr / 0.1)**2 )")   ->4.38ms#Numexpr (2.6.8), no SVML, single threadedne.evaluate("exp( - 0.5 * (myarr / 0.001)**2 )") ->50.85msne.evaluate("exp( - 0.5 * (myarr / 0.1)**2 )")   ->13.9ms

哈士奇WWW

这可能会产生减慢计算速度的非规范化数字。您可能想使用daz库禁用非规范化数字:import dazdaz.set_daz()更多信息:x87 和 SSE 浮点辅助 IA-32:Flush-To-Zero (FTZ) 和 Denormals-Are-Zero (DAZ):为避免由于非正规数和下溢数引起的序列化和性能问题,请使用 SSE 和 SSE2 指令在硬件中设置刷新为零和非正规数为零模式,以实现浮点应用程序的最高性能。请注意,在 64 位模式浮点计算中使用 SSE 指令,而不是 x87。
随时随地看视频慕课网APP

相关分类

Python
我要回答