12

numpy次のコードで実行時間の約50%を費やすスクリプトがあります。

s = numpy.dot(v1, v1)

どこ

v1 = v[1:]

連続したメモリに格納されたv4000要素の1Dndarrayです( is )。float64v.strides(8,)

これをスピードアップするための提案はありますか?

編集これはIntelハードウェア上にあります。これが私の出力ですnumpy.show_config()

atlas_threads_info:
    libraries = ['lapack', 'ptf77blas', 'ptcblas', 'atlas']
    library_dirs = ['/usr/local/atlas-3.9.16/lib']
    language = f77
    include_dirs = ['/usr/local/atlas-3.9.16/include']

blas_opt_info:
    libraries = ['ptf77blas', 'ptcblas', 'atlas']
    library_dirs = ['/usr/local/atlas-3.9.16/lib']
    define_macros = [('ATLAS_INFO', '"\\"3.9.16\\""')]
    language = c
    include_dirs = ['/usr/local/atlas-3.9.16/include']

atlas_blas_threads_info:
    libraries = ['ptf77blas', 'ptcblas', 'atlas']
    library_dirs = ['/usr/local/atlas-3.9.16/lib']
    language = c
    include_dirs = ['/usr/local/atlas-3.9.16/include']

lapack_opt_info:
    libraries = ['lapack', 'ptf77blas', 'ptcblas', 'atlas']
    library_dirs = ['/usr/local/atlas-3.9.16/lib']
    define_macros = [('ATLAS_INFO', '"\\"3.9.16\\""')]
    language = f77
    include_dirs = ['/usr/local/atlas-3.9.16/include']

lapack_mkl_info:
  NOT AVAILABLE

blas_mkl_info:
  NOT AVAILABLE

mkl_info:
  NOT AVAILABLE
4

4 に答える 4

5

アレイはそれほど大きくないので、ATLASはおそらくあまり機能していません。次のFortranプログラムのタイミングは何ですか?ATLASがあまり機能していないと仮定すると、Pythonのオーバーヘッドがない場合に、dot()がどれだけ高速になるかがわかります。gfortran -O3を使用すると、5 +/-0.5usの速度が得られます。

    program test

    real*8 :: x(4000), start, finish, s
    integer :: i, j
    integer,parameter :: jmax = 100000

    x(:) = 4.65
    s = 0.
    call cpu_time(start)
    do j=1,jmax
        s = s + dot_product(x, x)
    enddo
    call cpu_time(finish)
    print *, (finish-start)/jmax * 1.e6, s

    end program test
于 2011-05-13T18:51:34.557 に答える
5

おそらく、原因はdotに渡された配列のコピーです。

スヴェンが言ったように、ドット積はBLAS操作に依存しています。これらの操作には、連続したCの順序で格納された配列が必要です。dotに渡される両方の配列がC_CONTIGUOUSにある場合は、パフォーマンスが向上するはずです。

もちろん、ドットに渡される2つの配列が実際に1D(8、)である場合は、C_CONTIGUOUSフラグとF_CONTIGUOUSフラグの両方がTrueに設定されていることを確認する必要があります。しかし、それらが(1、8)の場合、混合順序を見ることができます。

>>> w = NP.random.randint(0, 10, 100).reshape(100, 1)
>>> w.flags
   C_CONTIGUOUS : True
   F_CONTIGUOUS : False
   OWNDATA : False
   WRITEABLE : True
   ALIGNED : True
   UPDATEIFCOPY : False


別の方法:モジュールscipy.linalg.fblasを通じて公開されるBLASの_GEMMを使用します。(2つの配列AとBは、 fblasが使用されているため、明らかにFortranの順序になっています。)

from scipy.linalg import fblas as FB
X = FB.dgemm(alpha=1., a=A, b=B, trans_b=True)
于 2011-05-13T12:08:51.023 に答える
4

これを加速するために私が考えることができるのは、NumPyインストールが最適化されたBLASライブラリ(ATLASなど)に対してコンパイルされていることを確認することだけです。 numpy.dot()は、BLASを利用する数少ないNumPy関数の1つです。

于 2011-05-13T10:32:19.183 に答える
2

numpy.dotは、正しくコンパイルされている場合、マルチスレッドを使用します。それがトップで行うことを確認してください。アトラス付きのnumpyでマルチスレッドが機能しなかったケースを知っています。さらに、Intelmklライブラリに対してコンパイルされたnumpyバージョンを使用してみる価値があります。それらには、Intelハードウェアのアトラスよりも高速であると思われるblasルーチンが含まれています。enthoughtのpythonディストリビューションを試してみることができます。これらすべてが含まれており、eduメールアカウントをお持ちの方は無料です。

于 2011-05-14T15:49:07.900 に答える