为了账号安全,请及时绑定邮箱和手机立即绑定

Numpy 性能差异取决于数值

Numpy 性能差异取决于数值

UYOU 2021-08-24 17:00:06
在评估 Numpy 中的表达式时,我发现了一个奇怪的性能差异。我执行了以下代码:import numpy as npmyarr = 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。这种行为的原因是什么?我可以更改某些内容以使第一次计算与第二次计算一样快吗?
查看完整描述

2 回答

?
ABOUTYOU

TA贡献1812条经验 获得超5个赞

使用英特尔 SVML

我没有numexpr使用英特尔 SVML,但numexpr使用 SVML 应该和 Numba 一样好。该Numba基准测试表明无SVML完全一样的行为,但SVML更好的表现。


代码


import numpy as np

import numba as nb


myarr = 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.6ms

func(myarr,0.001)                    -> 3.8ms


#Numba (set NUMBA_DISABLE_INTEL_SVML=1), parallel=True

func(myarr,0.1)                      -> 5.19ms

func(myarr,0.001)                    -> 12.0ms


#Numba (set NUMBA_DISABLE_INTEL_SVML=1), parallel=False

func(myarr,0.1)                      -> 16.7ms

func(myarr,0.001)                    -> 63.2ms


#Numpy (1.13.3), set OMP_NUM_THREADS=4

np.exp( - 0.5 * (myarr / 0.001)**2 ) -> 70.82ms

np.exp( - 0.5 * (myarr / 0.1)**2 )   -> 12.58ms


#Numpy (1.13.3), set OMP_NUM_THREADS=1

np.exp( - 0.5 * (myarr / 0.001)**2 ) -> 189.4ms

np.exp( - 0.5 * (myarr / 0.1)**2 )   -> 17.4ms


#Numexpr (2.6.8), no SVML, parallel

ne.evaluate("exp( - 0.5 * (myarr / 0.001)**2 )") ->17.2ms

ne.evaluate("exp( - 0.5 * (myarr / 0.1)**2 )")   ->4.38ms


#Numexpr (2.6.8), no SVML, single threaded

ne.evaluate("exp( - 0.5 * (myarr / 0.001)**2 )") ->50.85ms

ne.evaluate("exp( - 0.5 * (myarr / 0.1)**2 )")   ->13.9ms


查看完整回答
反对 回复 2021-08-24
?
哈士奇WWW

TA贡献1799条经验 获得超6个赞

这可能会产生减慢计算速度的非规范化数字。


您可能想使用daz库禁用非规范化数字:


import daz

daz.set_daz()

更多信息:x87 和 SSE 浮点辅助 IA-32:Flush-To-Zero (FTZ) 和 Denormals-Are-Zero (DAZ):


为避免由于非正规数和下溢数引起的序列化和性能问题,请使用 SSE 和 SSE2 指令在硬件中设置刷新为零和非正规数为零模式,以实现浮点应用程序的最高性能。


请注意,在 64 位模式浮点计算中使用 SSE 指令,而不是 x87。


查看完整回答
反对 回复 2021-08-24
  • 2 回答
  • 0 关注
  • 152 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号