2010-12-07 22 views
5
numpyでは、 xは大きな(200,000 x 1000)の高密度 float32行列で、 .Tは転置演算子ですか、 x.T * xを計算する最も効率的な方法は何ですか?

numpy:計算する。x *大きな行列の場合はx

疑問を避けるために、結果は1000 x 1000です。

:私の元の質問では、np.dot(x.T, x)は数時間かかると述べました。 NaNsがいくつかの理由でnp.dotのパフォーマンスを完全に無駄にしていたことが判明しました(理由は何ですか?)。これは今解決されていますが、元の質問が立っています。

答えて

10

これは、あなたが探している答えではないかもしれないが、かなりそれをスピードアップするための一つの方法ではなく、あなたのCPUのGPUを使用することです。非常に強力なグラフィックスカードがあれば、システムが非常にうまく調整されていても、いつでもあなたのCPUより優れたパフォーマンスを発揮します。

numpyとうまく統合するには、theano(グラフィックスカードがnvidia製の場合)を使用できます。次のコードでの計算は数秒で私のために動作します(私は非常に強力なグラフィックカードを持っているが):

$ THEANO_FLAGS=device=gpu0 python 
Python 2.6.5 (r265:79063, Apr 16 2010, 13:57:41) 
[GCC 4.4.3] on linux2 
Type "help", "copyright", "credits" or "license" for more information. 
>>> import theano 
Using gpu device 0: GeForce GTX 480 
>>> from theano import tensor as T 
>>> import numpy 
>>> x = numpy.ones((200000, 1000), dtype=numpy.float32) 
>>> m = T.matrix() 
>>> mTm = T.dot(m.T, m) 
>>> f = theano.function([m], mTm) 
>>> f(x) 
array([[ 200000., 200000., 200000., ..., 200000., 200000., 200000.], 
     [ 200000., 200000., 200000., ..., 200000., 200000., 200000.], 
     [ 200000., 200000., 200000., ..., 200000., 200000., 200000.], 
     ..., 
     [ 200000., 200000., 200000., ..., 200000., 200000., 200000.], 
     [ 200000., 200000., 200000., ..., 200000., 200000., 200000.], 
     [ 200000., 200000., 200000., ..., 200000., 200000., 200000.]], dtype=float32) 
>>> r = f(x) 
>>> r.shape 
(1000, 1000) 

私は比較としてかかった>>> numpy.dot(x.T, x)長く見つけるために待つつもりだったが、私退屈しました...

あなたはnumpyのサポートが簡単かどうかわかりませんが、PyCudaまたはPyOpenCL(nvidiaグラフィックスカードを持っていない場合)を試すこともできます。

+1

行列では、この大きなメモリは多くのグラフィックスカードの制約になると私は思いました。気をつけるべきこと。 –

+2

これは実際には素晴らしい選択肢ですが、CPUの乗算には多くの時間がかかりますが、確かに正常ではありません。 – steabert

+0

ポインタに感謝します。これは非常に面白く、確かに調べる価値があります。 – NPE

2

hmm、xは約800Mbです。結果が同じであると仮定した場合、物理メモリが十分にあり、スワップしていないのでしょうか?

以外の場合、numpyはBLAS関数を使用する必要があり、numpyが使用するデフォルトライブラリは比較的遅いかもしれませんが、このサイズでは正常に動作するはずです。

編集

import numpy as npy 
import time 

def mm_timing(): 
    print " n Gflops/s" 
    print "===============" 
    m = 1000 
    n = 200000 
    a = npy.random.rand(n, m) 
    flops = (2 * float(n) - 1) * float(m)**2 
    t1 = time.time() 
    c = npy.dot(a.T, a) 
    t2 = time.time() 
    perf = flops/(t2 - t1)/1.e9 
    print "%4i" % n + "  " + "%6.3f" % perf 

mm_timing() 
+0

@steabert(vmstatで示されているように)スワップしていないことを確かめてください。また、コアの100%を占めていますが、I/Oバウンドの場合はそうではありません。他に何かが起こっているはずです。 – NPE

+0

いくつかの小さな行列の行列乗算でどのようなFLOPSを測定しますか? – steabert

+0

@steabertこのために実行する標準的なベンチマークは何ですか? – NPE

5

まず、最適化されたblas/lapackを使用することをお勧めします。これは大きな違いをもたらします(最大1桁まで)。たとえば、スレッドATLASを使用すると、すべてのコアが比較的効率的に使用されます(ATLASをコンパイルするのは最近のATLASを使用する必要があり、ATLASはPITAです)。

なぜNanはすべての処理を遅くするのですか:それはかなり避けられないことですが、NaNの処理はCPUレベルの「通常の」浮動小数点よりもはるかに遅いです:http://www.cygnus-software.com/papers/x86andinfinity.html。これは、CPUモデル、使用している命令セットの種類、使用しているアルゴリズム/実装によって異なります。

+0

「NaNの処理は、通常の「CPUレベルで浮動」よりもはるかに遅い」というバックアップを作成するための参照はありますか?私が見つけた唯一のものはhttp://stackoverflow.com/questions/3606054/how-slow-is-nan-arithmetic-in-the-intel-x64-fpu/3606088#3606088です。ありがとう – NPE

+0

は1つのリンクを追加しました。減速は多くのパラメータに依存するため、1つの理由を特定するのは難しく、ケースごとに行われます。 –

関連する問題