<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                # 1.13。性能提示 > 原文: [http://numba.pydata.org/numba-doc/latest/user/performance-tips.html](http://numba.pydata.org/numba-doc/latest/user/performance-tips.html) 這是 Numba 中功能的簡短指南,可以幫助您從代碼中獲得最佳性能。使用了兩個例子,兩者都完全是人為的,純粹出于教學原因而存在,以激發討論。第一個是三角恒等式`cos(x)^2 + sin(x)^2`的計算,第二個是矢量的簡單元素方形平方根,它是求和的減少。所有性能數字僅供參考,除非另有說明,否則選自在`np.arange(1.e7)`輸入的英特爾`i7-4790` CPU(4 個硬件線程)上運行。 注意 實現高性能代碼的一種合理有效的方法是使用實??際數據分析運行的代碼,并使用它來指導性能調優。這里提供的信息是為了展示功能,而不是作為規范指導! ## 1.13.1。沒有 Python 模式與對象模式 一個常見的模式是用`@jit`來裝飾函數,因為這是 Numba 提供的最靈活的裝飾器。 `@jit`本質上包含兩種編譯模式,首先它將嘗試在沒有 Python 模式下編譯裝飾函數,如果失敗,它將再次嘗試使用對象模式編譯函數。雖然在對象模式下使用循環可以提高性能,但是在無 python 模式下編譯函數確實是獲得良好性能的關鍵。為了使得只使用沒有 python 模式,并且如果編譯失敗,則引發異常,可以使用裝飾器`@njit`和`@jit(nopython=True)`(為方便起見,第一個是第二個的別名)。 ## 1.13.2。循環 雖然 NumPy 在矢量運算的使用方面已經形成了一個強有力的習慣,但 Numba 對循環也非常滿意。對于熟悉 C 或 Fortran 的用戶,以這種方式編寫 Python 在 Numba 中可以正常工作(畢竟,LLVM 在編譯 C 譜系語言時有很多用處)。例如: ```py @njit def ident_np(x): return np.cos(x) ** 2 + np.sin(x) ** 2 @njit def ident_loops(x): r = np.empty_like(x) n = len(x) for i in range(n): r[i] = np.cos(x[i]) ** 2 + np.sin(x[i]) ** 2 return r ``` 當用`@njit`修飾時,上面以幾乎相同的速度運行,沒有裝飾器,矢量化功能的速度提高了幾個數量級。 | 功能名稱 | @njit | 執行時間處理時間 | | --- | --- | --- | | `ident_np` | 沒有 | 0.581s | | `ident_np` | 是 | 0.659s | | `ident_loops` | 沒有 | 25.2s | | `ident_loops` | 是 | 0.670s | ## 1.13.3。 Fastmath 在某些類別的應用中,嚴格的 IEEE 754 合規性不那么重要。因此,可以放松一些數字嚴謹性,以獲得額外的性能。在 Numba 中實現此行為的方法是使用`fastmath`關鍵字參數: ```py @njit(fastmath=False) def do_sum(A): acc = 0. # without fastmath, this loop must accumulate in strict order for x in A: acc += np.sqrt(x) return acc @njit(fastmath=True) def do_sum_fast(A): acc = 0. # with fastmath, the reduction can be vectorized as floating point # reassociation is permitted. for x in A: acc += np.sqrt(x) return acc ``` | 功能名稱 | 執行時間處理時間 | | --- | --- | | `do_sum` | 35.2 毫秒 | | `do_sum_fast` | 17.8 毫秒 | ## 1.13.4。并行=真 如果代碼包含可并行的操作([和支持](parallel.html#numba-parallel-supported)),Numba 可以編譯一個版本,它將在多個本機線程上并行運行(沒有 GIL!)。這種并行化是自動執行的,只需添加`parallel`關鍵字參數即可啟用: ```py @njit(parallel=True) def ident_parallel(A): return np.cos(x) ** 2 + np.sin(x) ** 2 ``` 執行時間如下: | 功能名稱 | 執行時間處理時間 | | --- | --- | | `ident_parallel` | 112 毫秒 | 存在`parallel=True`的此功能的執行速度約為 NumPy 等效值的 5 倍,是標準`@njit`的 6 倍。 Numba 并行執行也支持顯式并行循環聲明,類似于 OpenMP。為了表明應該并行執行循環,應該使用`numba.prange`函數,這個函數的行為類似于 Python `range`,如果沒有設置`parallel=True`,它只是作為`range`的別名。用`prange`誘導的循環可用于令人尷尬的并行計算和減少。 重新考慮 reduce over sum 示例,假設無法按順序累積總和是安全的,`n`中的循環可以通過使用`prange`來并行化。此外,在這種情況下可以毫無顧慮地添加`fastmath=True`關鍵字參數,因為已經通過使用`parallel=True`(因為每個線程計算部分和)已經進行了無序執行有效的假設。 ```py @njit(parallel=True) def do_sum_parallel(A): # each thread can accumulate its own partial sum, and then a cross # thread reduction is performed to obtain the result to return n = len(A) acc = 0. for i in prange(n): acc += np.sqrt(A[i]) return acc @njit(parallel=True, fastmath=True) def do_sum_parallel_fast(A): n = len(A) acc = 0. for i in prange(n): acc += np.sqrt(A[i]) return acc ``` 執行時間如下,`fastmath`再次提高性能。 | 功能名稱 | 執行時間處理時間 | | --- | --- | | `do_sum_parallel` | 9.81 毫秒 | | `do_sum_parallel_fast` | 5.37 毫秒 | ## 1.13.5。英特爾 SVML 英特爾提供了一個簡短的矢量數學庫(SVML),其中包含大量優化的超越函數,可用作編譯器內在函數。如果環境中存在`icc_rt`包(或者 SVML 庫只是可定位的!),那么 Numba 會自動配置 LLVM 后端以盡可能使用 SVML 內部函數。 SVML 提供每個內在函數的高精度和低精度版本,并且使用的版本通過使用`fastmath`關鍵字來確定。默認使用精度高于`1 ULP`的高精度,但如果`fastmath`設置為`True`,則使用內在函數的低精度版本(`4 ULP`內的答案)。 首先使用 conda 獲取 SVML,例如: ```py conda install -c numba icc_rt ``` 從上面重新運行身份函數示例`ident_np`,使用`@njit`和/或不使用 SVML 的各種選項組合,得到以下性能結果(輸入大小`np.arange(1.e8)`)。作為參考,僅使用 NumPy 在`5.84s`中執行的功能: | `@njit` kwargs | SVML | 執行時間處理時間 | | --- | --- | --- | | `None` | 沒有 | 5.95s | | `None` | 是 | 2.26s | | `fastmath=True` | 沒有 | 5.97s | | `fastmath=True` | 是 | 1.8 秒 | | `parallel=True` | 沒有 | 1.36s | | `parallel=True` | 是 | 0.624s | | `parallel=True, fastmath=True` | 沒有 | 1.32s | | `parallel=True, fastmath=True` | 是 | 0.576s | 很明顯,SVML 顯著提高了該功能的性能。在不存在 SVML 的情況下`fastmath`的影響是零,這是預期的,因為原始函數中沒有任何東西可以從放寬數字嚴格性中受益。 ## 1.13.6。線性代數 Numba 在沒有 Python 模式的情況下支持大多數`numpy.linalg`。內部實現依賴于 LAPACK 和 BLAS 庫來完成數值工作,并從 SciPy 獲取必要函數的綁定。因此,要在 Numba 的`numpy.linalg`函數中實現良好的性能,必須使用針對優化良好的 LAPACK / BLAS 庫構建的 SciPy。在 Anaconda 發行版的情況下,SciPy 是針對英特爾的 MKL 構建的,該版本經過高度優化,因此 Numba 利用了這一性能。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看