2011-10-22 67 views
2

我是一位正在努力學習一點關於這種奇妙編程語言的Python新手。我曾嘗試使用scipy.weave.inline來加速一些計算。爲了學習一點,我嘗試使用scipy.weave.inline實現矩陣乘法。我沒有包含任何錯誤處理 - 只是試圖更好地理解它。代碼如下:scipy.weave.inline的性能

import scipy.weave 
def cmatmul(A,B): 
    R = numpy.zeros((A.shape[0],B.shape[1])) 
    M = R.shape[0] 
    N = R.shape[1] 
    K = A.shape[1] 

    code = \ 
    """ 
    for (int i=0; i<M; i++) 
     for (int j=0; j<N; j++) 
      for (int k=0; k<K; k++) 
       R(i,j) += A(i,k) * B(k,j); 
    """ 
    scipy.weave.inline(code, ['R','A','B','M','N','K'], \ 
         type_converters=scipy.weave.converters.blitz, \ 
         compiler='gcc') 
    return R 

當我numpy.dot相比,我的經驗表明,weave.inline版本需要大約50倍的時間numpy.dot。我知道numpy在應用時速度非常快。差異甚至可見於大型矩陣,例如大小爲1000 x 1000.

我檢查了numpy.dot和scipy.weave.inline,並且兩者在計算時似乎都使用一個核心100%。 Numpy.dot提供了10.0 GFlops相比,我的筆記本電腦的理論11.6 GFlops(雙精度)。在單精度我測量雙倍性能如預期。但scipy.weave.inline落後了。這是scipy.weave.inline的1/50倍。

這是不同的預期?或者我做錯了什麼?

+0

(我不是性能大師。)'numpy'對象已經很低級了:所有的矩陣操作都是用快速編譯的代碼編寫的。 'weave.inline'比原生Python好,但不如默認的numpy。我的機器上有' – katrielalex

+0

':'cmatmul'需要9.7秒(如果'B'具有Fortran內存佈局則爲'4.9'),'np.dot' - '0.27'爲1000x1000實矩陣。 – jfs

+0

好的。沒有我看到的那麼大,但趨勢是一樣的。這不是因爲我在上面的代碼中做了錯誤的事情,或者省略了一些編譯器標誌? – Lars1

回答

7

您實現了一種樸素矩陣乘法算法,scipy.weave編譯爲快速機器碼。

但是,有非常明顯的CPU緩存效率更高algorithms for matrix multiplication(它通常會將矩陣分成塊並處理這些塊),並且可以通過CPU特定的優化獲得額外的速度。如果您安裝了Numpy,則默認情況下Numpy使用優化的BLAS庫進行此操作。與沒有進行大量研究的情況下自行編碼的任何內容相比,這些庫可能會很快。

+0

我知道比n * 2 *(2 * n-1)乘法和加法的天真方法更有效的算法存在。在最近的GeMM措施中,我已經看到增加和乘法似乎在成本方面是平等對待的。但是,您對特定優化的評論以及可能比天真方法更好的緩存利用率的作用比我預期的要大。看到如此巨大的差異,我有點驚訝。感謝您的信息。 – Lars1