亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

為什么與使用兩個 Numpy 數組的向量化相比,使用 Numpy 數組和 int 進行算術運算時減

為什么與使用兩個 Numpy 數組的向量化相比,使用 Numpy 數組和 int 進行算術運算時減

嚕嚕噠 2022-06-28 11:12:20
我對為什么這段代碼感到困惑:start = time.time()for i in range(1000000):    _ = 1 - np.log(X)print(time.time()-start)執行速度比這個實現快:start = time.time()for i in range(1000000):    _ = np.subtract(np.ones_like(X), np.log(X))print(time.time()-start)我的理解是它應該是相反的,因為在第二個實現中我正在利用矢量化提供的加速,因為它能夠同時操作 X 中的元素而不是順序操作,這就是我假設第一個實現的方式功能。有人可以為我解釋一下嗎,因為我真的很困惑?謝謝!
查看完整描述

4 回答

?
有只小跳蛙

TA貢獻1824條經驗 獲得超8個贊

您的代碼的兩個版本都是矢量化的。您為嘗試向量化第二個版本而創建的數組只是開銷。


NumPy 向量化不是指硬件向量化。如果編譯器足夠聰明,它最終可能會使用硬件矢量化,但 NumPy 并沒有明確使用 AVX 或任何東西。

NumPy 向量化是指編寫一次對整個數組進行操作的 Python 級代碼,而不是使用一次對多個操作數進行操作的硬件指令。它是 Python 級別的向量化,而不是機器語言級別的向量化。與編寫顯式循環相比,這樣做的好處是 NumPy 可以在 C 級循環而不是 Python 中執行工作,從而避免了大量的動態調度、裝箱、拆箱、遍歷字節碼評估循環等。

從這個意義上說,您的代碼的兩個版本都是矢量化的,但是第二個版本在寫入和讀取巨大的數組時浪費了大量內存和內存帶寬。

此外,即使我們談論的是硬件級矢量化,該1 -版本也與其他版本一樣適用于硬件級矢量化。您只需將標量加載1到向量寄存器的所有位置并正常進行。與第二個版本相比,它涉及的內存傳輸要少得多,因此可能仍然比第二個版本運行得更快。


查看完整回答
反對 回復 2022-06-28
?
楊魅力

TA貢獻1811條經驗 獲得超6個贊

時間基本相同。正如其他人指出的那樣,沒有任何類型的硬件或多核并行化,只是解釋 Python 和編譯numpy函數的混合。


In [289]: x = np.ones((1000,1000))


In [290]: timeit 1-np.log(x)                                                    

15 ms ± 1.94 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)


In [291]: timeit np.subtract(np.ones_like(x), np.log(x))                        

18.6 ms ± 1.89 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

取出np.ones_like定時循環:


In [292]: %%timeit y = np.ones_like(x) 

     ...: np.subtract(y,np.log(x)) 

     ...:  

     ...:                                                                       

15.7 ms ± 441 μs per loop (mean ± std. dev. of 7 runs, 100 loops each)

2/3 的時間花在log函數上:


In [303]: timeit np.log(x)                                                      

10.7 ms ± 211 μs per loop (mean ± std. dev. of 7 runs, 100 loops each)

In [306]: %%timeit y=np.log(x) 

     ...: np.subtract(1, y)                                                                  

3.77 ms ± 5.16 μs per loop (mean ± std. dev. of 7 runs, 100 loops each)

生成方式的變化1只是時間的一小部分。


使用“廣播”,使用標量和數組或數組和數組進行數學運算同樣容易。


,1無論是標量(實際上是一個形狀為 的數組()),被廣播到 (1,1),然后到 (1000,1000),所有這些都沒有復制。


查看完整回答
反對 回復 2022-06-28
?
aluckdog

TA貢獻1847條經驗 獲得超7個贊

我當然不是 numpy 專家,但我的猜測是第一個例子只使用一個向量,第二個例子首先創建了一個 1 的向量,然后減去。后者需要雙倍的內存和一個額外的步驟來創建 1 的向量。

在 x86 CPU 上,兩者都可能是某種 AVX 指令,一次可以處理 4 個數字。當然,除非您使用的是 SIMD 寬度大于向量長度的花哨 CPU,并且該 CPU 由 numpy 支持。


查看完整回答
反對 回復 2022-06-28
?
慕桂英546537

TA貢獻1848條經驗 獲得超10個贊

案例 A 在 mpu 上僅運行一個迭代器,而案例 B 在兩個與 X 一樣大的向量上具有兩個迭代器,如果未優化,則需要在線程中進行大量上下文切換。案例 B 是案例 A 的更通用版本......



查看完整回答
反對 回復 2022-06-28
  • 4 回答
  • 0 關注
  • 146 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號