淘新聞

如何在 i5 上實現 20 倍的 Python 運行速度?

Intel Distribution for Python 在今年二月進行了更新——英特爾發佈了 Update 2 版本。以“加速”為核心的它,相比原生 Python 環境有多大提升呢?

雷鋒網獲知,平行計算專家、前英特爾高級工程師 James Reinders 對老東家的產品進行了測試。他對外宣佈:

在配備四核 i5 的 iMAC 上實現了 20 倍的性能加速!

至於他是怎麼做到的,請繼續往下看(含代碼)。

James Reinders

James Reinders:

利用 Intel Distribution for Python,我實現了 Python 的 20 倍加速,並且可用單個命令關閉/啟用。這還不是在最優情況下,而在虛擬環境——在 VirtualBox(下文簡稱 VBox) 上運行的 openSUSE Linux Tumbleweed(即“滾動版本”,請參考 openSUSE 

官網

),使用的機器是四核 iMac。

這在 Windows, Linux 或 OS X 都能實現。英特爾並沒有把 openSUSE 加入經他們測試過的 Linux 配置清單中(SUSE Enterprise 在表中),但我在運行中並沒有遇到任何問題。

這就是我怎麼做的:

下載 Anaconda 命令列安裝程式,位址為 

https://www.continuum.io/downloads

 。

安裝: % bash Anaconda2-4.3.0-Linux-x86_64.sh

安裝英特爾加速器,作為一個單獨的、可開啟關閉的“環境”:% conda config --add channels intel % conda create --name intelpy intelpython2_full python=2

運行示例程式,看到在我的 openSUSE VBox 設置上有 15 到 20 倍的速度提升。

% source deactivate intelpy

% python <>

np.sin

102400 10000 36.1987440586

np.cos

102400 10000 36.1938228607

np.tan

102400 10000 51.487637043

% source activate intelpy

% python <>

np.sin

102400 10000 1.76131296158

np.cos

102400 10000 1.83870100975

np.tan

102400 10000 3.38778400421

That’s all! The speed-ups are 20.6X, 19.7X, and 15.2X in this quick test running on a virtual machine.

Here’s my little Python program:

% cat myprog.py

import numpy as np

import time

N = 102400

x = np.linspace(0.0123, 4567.89, N)

def mine(x,Z,func,name):

print name;

start = time.time()

for z in range ( 0, Z ) :

y = func(x);

end = time.time()

print N, Z, end - start

return

mine(x,10000,np.sin,'np.sin')

mine(x,10000,np.cos,'np.cos')

mine(x,10000,np.tan,'np.tan')

我花很短時間搞起來這個程式,用來驗證英特爾對加速 NumPy 中 transcendental expression 的承諾。 Cosine, sine 和 tangent 是我還能記得的、搞 TI calculator 時候用的 transcendental,所以我用它們來試。我決定對每一個進行十億級測試——運行超過十萬個數位的函數,重複超過一萬次。

雖然未必是一個很有意思的程式,但對於加速而言是個不錯的測試。

隨時加速 Python

我此前寫過一篇

文章

,討論“Python 加速”( “accelerated Python” )使其更適用於大資料和 HPC 應用。 在速度更快之外,我還展示了,使用 Conda 來開啟/關閉加速是多麼得容易。這非常贊,讓安裝它的決定變得更加安全、沒有顧慮——因為該功能是一個可選項。(對新手的提醒: Anaconda 是針對 Python 演算法包的集合,Conda 則是 package manager,即演算法包管理器。我兩個都用並且都很喜歡。)

我使用 “conda create”來創造被我稱之為 intelpy 的環境。然後,我能夠使用 “source activate intelpy”、“source deactivate intelpy”來啟動、關閉它。

Intel Distribution for Python 帶來的大幅加速能力,讓 “accelerated Python” 變得更實用更讓人信服。

值得注意的是, “accelerated Python” 只是使用更快的 Python 演算法庫,不需要對代碼做任何改動。當然,我們的 Python 代碼必須使用了某些加速的東西,才能從中獲益。

據雷鋒網得知,英特爾通過三大方面實現 Python 加速:

利用多核;

利用向量指令(SIMD),比如 SSE, AVX, AVX2 和 AVX-512;

使用英特爾 Math Kernel Library (Intel MKL) 的更先進演算法。

對於運行於向量或矩陣上的程式,上述這些都會生效。對於偶爾的單獨 cosine,我們不應該期待大幅速度提升。同樣的,對於單核 CPU,我們也不應該有性能提升的幻想。當然,英特爾 72 核輔助處理器 Xeon Phi 會在大量多核應用的跑分中領先。在我的例子中,我的虛擬機器只利用 iMac i5 的四個核心。

FFT 在 4 核虛擬機器上有八倍性能提升

我也試了下 Fast Fourier Transforms (FFT)。使用與原始程式相同的設置,我只是按照如下方式運行 FFT 程式:

% source deactivate intelpy

% python <>

fft

5000 2.22796392441

fft

7000 8.74916005135

% source activate intelpy

% python <>

fft

5000 0.277629137039

fft

7000 1.11230897903

速度提升為 8 和 7.9 倍。當然,還是運行於四核 iMac 上的 openSUSE 和 VBox。

這是我的快速 FFT 程式:

% cat myfftprog.py

import numpy as np

import numpy.random as rn

import time

def trythis(Z):

mat = rn.rand(Z,Z) + 1j * rn.randn(Z,Z)

print 'fft'

start = time.time()

# 2D transform on a complex-valued matrix:

result = np.fft.fft2(mat)

end = time.time()

print Z, end - start

return

trythis(5000);

trythis(7000);

新 Python 加速

雷鋒網瞭解到,以下是 Intel Distribution for Python 全新 Update 2 版本中,得到了新的速度提升的方面:

優化 NumPy 的算術和 transcendental 表達

Transcendental expressions 包含我在快速示例程式裡用的 cosine, sine 和 tangen。這些優化的核心是對 NumPy 的改變,使得 primitives (在 ndarray 資料上進行運算)能選擇性地使用英特爾 MKL Short Vector Math Library (SVML) 和 MKL Vector Math Library (VML) 的能力。這使得 Python 利用處理器的最新向量能力,包括多核優化和 AVX/AVX2/AVX-512。英特爾團隊表示,他們利用 Xeon Phi,實現過 NumPy 算術和 transcendental 運算在 vector-vector 和 vector-scalar 上最高 400 倍的速度提升。

優化 NumPy 和 SciPy 的 FFT

這些優化的核心是英特爾 MKL,一系列 NumPy、SciPy 函數都能用到它對 FFT 的原生優化。這些優化包含真實、複雜的資料類型,單精確度和雙精度都包含 ( single and double precision),從一維到多維的資料,in place 或者 out of place。英特爾團隊見到過這項更新帶來 60 倍的性能提升。

這使得 Python 的性能可與原生 C/C++ 程式相媲美。

優化記憶體管理

Python 是一門動態語言,為使用者管理記憶體。Python 應用的性能,在很大程度上取決於記憶體運行的性能,這包括記憶體分配、再分配(de-allocation)、複製和移動。英特爾提供的加速版本 Python,能在 NumPy 分配陣列時保證最佳的 alignment,所以 NumPy、SciPy 的運算函數,能從相應排列的 SIMD 記憶體訪問指令獲益。英特爾表示最大的提升來自於對記憶體複製和移動運算的優化。

更快——能用 Conda 方便地關閉/啟用

Anaconda 英特爾管道的最新加速版本 Python,為 Python 程式帶來顯著性能優化,而無需改變代碼。下載、安裝也很方便。

我真的特喜歡用 Conda 把它開啟/關閉這一功能。這方便了性能對比,並且讓我感到安心——沒有這個功能的話,我會對切換到超快的數學函數感到猶豫。

via 

infoworld