Python為何在科學計算領域打敗Fortran? - cerfacs

banq發表於2022-03-29

為什麼越來越多以前在 Fortran 中執行的時間要求嚴格的科學計算現在用 Python 這種速度較慢的語言編寫?
Python 以速度慢著稱,即比 Fortran、C 或 Rust 等編譯語言慢得多。普通的 Python 比 Fortran 慢得多。

然而,這種比較毫無意義,因為 Python 的科學用途並不依賴於普通的 Python。相反,Python 被用作粘合層,依賴於編譯的最佳化包,將它們串在一起以執行目標計算。

科學計算中最廣泛的軟體包可能是NumPy,即Numerical Python。
 顧名思義,數字資料是透過這個包來操作的,而不是在普通的Python中,在幕後所有繁重的工作都是由C/C++或Fortran編譯的例程完成的。
從本質上講,Python被用來將一個快速例程指向正確的方向(即指向正確的記憶體地址),僅此而已。

比較brute-force(Fortran)和基於KDtree的(Python / NumPy / SciPy)效能時間:
  • 10億個細胞
  • 1000萬個多孔的邊界節點
  • 1.8萬個穿孔

brute-force的版本執行了6小時30分鐘;而基於Kdtree的版本呢?只用了4分鐘,幾乎快了100倍,結果的差異只在機器精度的層面上出現。
 
詳細點選標題
 
Reddit網友評論:
1. 這與我的經歷產生了共鳴。在我之前的研究小組中,有一個模擬量很大的專案在不到兩個月的時間內從構思到手稿,因為它能夠利用 Numpy、Numba 和 Scipy。如果它是用另一種語言完成的,我很難相信它會這麼快釋出(即使最終的模擬可能會稍微快一點)。
 
2. Numpy是~120萬行的C語言,不是因為它是一個薄薄的BLAS封裝,而是因為它本身就是一個大型的數值庫。

numpy的一部分,np.linalg使用BLAS後端,以及dot、matmul和tensordot。你的普通函式 "ufuncs "如加、減、乘、除根本不使用BLAS,只是一個C語言的for迴圈。在最近的numpy中,exp也使用AVX-512(它是在1.18或1.19中新增的,我忘了是哪個)。

如果你在純numpy中做arr1 * arr2,你可以在低階語言中透過不分配來打敗它,儘管np.mul(arr1, arr2, out=out)讓你在numpy中獲得不分配的風格,而且numpy記憶體池可能使分配基本免費。

然而,在低階語言中,你將有能力分割出arr1, arr2並進行多執行緒操作,而numpy不能做到這一點。

另一方面,numpy不遺餘力地以最佳順序執行記憶體訪問,許多操作(檢視等)基本上是免費的,它記錄了步長和迭代順序而不是移動資料。C++庫(BOOST、Eigen)沒有這些最佳化。

編譯器也可能在低階語言中融合迴圈,這在numpy中非常明確地不會發生。

還有一些操作在numpy中是不存在的,在低階語言中可以很容易地實現,例如用一個矩陣乘以一個對角線矩陣,你把它作為一個向量儲存。
 
3.Python中的計算任務通常利用高度最佳化的庫。Python的成功一直取決於兩件事...
  • 開發速度是程式設計中存在的一個問題。
  • 對非時間限制的程式碼進行執行時間最佳化總是在浪費開發時間。

Python在科學領域勝出,因為它提供了一個完整的軟體包,由於其直觀的成語風格,開發速度快,由於其有效利用低階開發庫的模組化,執行速度快。
 

相關文章