高效能的Python擴充套件(1)

Janzou發表於2014-10-28

簡介

通常來說,Python不是一種高效能的語言,在某種意義上,這種說法是真的。但是,隨著以Numpy為中心的數學和科學軟體包的生態圈的發展,達到合理的效能不會太困難。

當效能成為問題時,執行時間通常由幾個函式決定。用C重寫這些函式,通常能極大的提升效能。

在本系列的第一部分中,我們來看看如何使用NumPy的C API來編寫C語言的Python擴充套件,以改善模型的效能。在以後的文章中,我們將在這裡提出我們的解決方案,以進一步提升其效能。

檔案

這篇文章中所涉及的檔案可以在Github上獲得。

模擬

作為這個練習的起點,我們將在像重力的力的作用下為N體來考慮二維N體的模擬。

以下是將用於儲存我們世界的狀態,以及一些臨時變數的類。

在開始模擬時,N體被隨機分配質量m,位置r和速度v。對於每個時間步長,接下來的計算有:

  1. 合力F,每個體上的合力根據所有其他體的計算。
  2. 速度v,由於力的作用每個體的速度被改變。
  3. 位置R,由於速度每個體的位置被改變。

第一步是計算合力F,這將是我們的瓶頸。由於世界上存在的其他物體,單一物體上的力是所有作用力的總和。這導致複雜度為O(N^2)。速度v和位置r更新的複雜度都是O(N)。

如果你有興趣,這篇維基百科的文章介紹了一些可以加快力的計算的近似方法。

純Python

在純Python中,使用NumPy陣列是時間演變函式的一種實現方式,它為優化提供了一個起點,並涉及測試其他實現方式。

合力計算的複雜度為O(N^2)的現象被NumPy的陣列符號所掩蓋。每個陣列操作遍歷陣列元素。

視覺化

這裡是7個物體從隨機初始狀態開始演化的路徑圖:

State Machine Diagram

效能

為了實現這個基準,我們在專案目錄下建立了一個指令碼,包含如下內容:

我們使用cProfile模組來測試衡量這個指令碼。

前幾行告訴我們,compute_F確實是我們的瓶頸,它佔了超過99%的執行時間。

在Intel i5桌上型電腦上有101體,這種實現能夠通過每秒257個時間步長演化世界。

簡單的C擴充套件 1

在本節中,我們將看到一個C擴充套件模組實現演化的功能。當看完這一節時,這可能幫助我們獲得一個C檔案的副本。檔案src/simple1.c,可以在GitHub上獲得。

關於NumPy的C API的其他文件,請參閱NumPy的參考。Python的C API的詳細文件在這裡

樣板

檔案中的第一件事情是先宣告演化函式。這將直接用於下面的方法列表。

接下來是方法列表。

這是為擴充套件模組的一個匯出方法列表。這隻有一個名為evolve方法。

樣板的最後一部分是模組的初始化。

另外,正如這裡顯示,initsimple1中的名稱必須與Py_InitModule中的第一個引數匹配。對每個使用NumPy API的擴充套件而言,呼叫import_array是有必要的。

陣列訪問巨集

陣列訪問的巨集可以在陣列中被用來正確地索引,無論陣列被如何重塑或分片。這些巨集也使用如下的程式碼使它們有更高的可讀性。

在這裡,我們看到訪問巨集的一維和二維陣列。具有更高維度的陣列可以以類似的方式被訪問。

在這些巨集的幫助下,我們可以使用下面的程式碼迴圈r:

命名標記

上面定義的巨集,只在匹配NumPy的陣列物件定義了正確的名稱時才有效。在上面的程式碼中,陣列被命名為py_mpy_r。為了在不同的方法中使用相同的巨集,NumPy陣列的名稱需要保持一致。

計算力

特別是與上面五行的Python程式碼相比,計算力陣列的方法顯得頗為繁瑣。

請注意,我們使用牛頓第三定律(成對出現的力大小相等且方向相反)來降低內環範圍。不幸的是,它的複雜度仍然為O(N^2)。

演化函式

該檔案中的最後一個函式是匯出的演化方法。

在這裡,我們看到了Python引數如何被解析。在該函式底部的時間步長迴圈中,我們看到的速度和位置向量的x和y分量的顯式計算。

效能

C版本的演化方法比Python版本更快,這應該不足為奇。在上面提到的相同的i5桌上型電腦中,C實現的演化方法能夠實現每秒17972個時間步長。相比Python實現,這方面有70倍的提升。

觀察

注意,C程式碼一直保持儘可能的簡單。輸入引數和輸出矩陣可以進行型別檢查,並分配一個Python裝飾器函式。刪除分配,不僅能加快處理,而且消除了由Python物件不正確的引用計數造成的記憶體洩露(或更糟)。

下一部分

在本系列文章的下一部分,我們將通過發揮C-相鄰NumPy矩陣的優勢來提升這種實現的效能。之後,我們來看看使用英特爾的SIMD指令和OpenMP來進一步推進。

如果您有任何疑問,意見,建議或更正,請通過聯絡連結告訴我。

相關文章