web-dev-qa-db-ja.com

python / numpyのマルチスレッドblas

私はPythonで多数の行列-行列乗算を実装しようとしています。最初に、私はNumPyがスレッド化されたBLASライブラリーを自動的に使用することを想定しました。これらのライブラリーに対してビルドしたからです。しかし、 top または何か他のものを見ると、コードはまったくスレッドを使用していないようです。

何が間違っているのか、BLASパフォーマンスを簡単に使用するために何ができるのか?

44
Lucas

NumPyのすべてがBLASを使用しているわけではなく、一部の関数、具体的にはdot()vdot()、およびinnerproduct()およびnumpy.linalgモジュール。また、多くのNumPy操作は、大きなアレイのメモリ帯域幅によって制限されるため、最適化された実装では改善が見込めないことに注意してください。メモリ帯域幅によって制限されている場合にマルチスレッドがより良いパフォーマンスを提供できるかどうかは、ハードウェアに大きく依存します。

17
Sven Marnach

私はすでに別のスレッドでこれを投稿しましたが、私はこの方がより適切だと思います:

更新(2014年7月30日):

新しいHPCでベンチマークを再実行します。ハードウェアとソフトウェアスタックの両方が、元の回答のセットアップから変更されました。

結果を googleスプレッドシート に入れます(元の回答の結果も含まれています)。

ハードウェア

HPCには、Intel Sandy Bridge CPUと新しいIvy Bridge CPUを搭載した2つの異なるノードがあります。

Sandy(MKL、OpenBLAS、ATLAS):

  • [〜#〜] cpu [〜#〜]:2 x 16 Intel(R)Xeon(R)E2560 Sandy Bridge @ 2.00GHz(16コア)
  • [〜#〜] ram [〜#〜]:64 GB

Ivy(MKL、OpenBLAS、ATLAS):

  • [〜#〜] cpu [〜#〜]:2 x 20 Intel(R)Xeon(R)E2680 V2 Ivy Bridge @ 2.80GHz(20コア、HT = 40コア)
  • [〜#〜] ram [〜#〜]:256 GB

ソフトウェア

ソフトウェアスタックは、両方のノード用です。 GotoBLAS2の代わりに、OpenBLASが使用され、8スレッド(ハードコード化)に設定されたマルチスレッドATLAS BLASもあります。

  • [〜#〜] os [〜#〜]:Suse
  • Intel Compiler:ictce-5.3.0
  • Numpy: 1.8.0
  • OpenBLAS: 0.2.6
  • ATLAS::3.8.4

ドット積ベンチマーク

ベンチマークコードは以下と同じです。ただし、新しいマシンでは、マトリックスサイズ50および80のベンチマークも実行しました。
次の表には、元の回答のベンチマーク結果が含まれています(名前を変更:MKL-> Nehalem MKL、Netlib Blas-> Nehalem Netlib BLASなど)

Matrix multiplication (sizes=[1000,2000,3000,5000,8000])

シングルスレッドパフォーマンス: single threaded performance

マルチスレッドパフォーマンス(8スレッド): multi-threaded (8 threads) performance

スレッドとマトリックスサイズ(Ivy Bridge MKL): Matrix-size vs threads

ベンチマークスイート

benchmark suite

シングルスレッドパフォーマンス: enter image description here

マルチスレッド(8スレッド)パフォーマンス: enter image description here

結論

新しいベンチマークの結果は、元の回答の結果と似ています。 OpenBLASおよび[〜#〜] mkl [〜#〜]Eigenvalueテストを除き、同じレベルで実行します。 Eigenvalueテストは、OpenBLAS in single threaded modeでのみ十分に機能します。マルチスレッドモードでは、パフォーマンスが低下します。

"Matrix size vs threadsチャート"は、MKLとOpenBLASが一般にコア/スレッドの数に応じて適切にスケーリングするが、マトリックスのサイズに依存することも示しています。小さなマトリックスの場合、コアを追加してもパフォーマンスはあまり向上しません。

また、Sandy BridgeからIvy Bridgeに約30%のパフォーマンスの向上があります。これは、クロックレートの高速化(+ 0.8 Ghz)および/またはアーキテクチャの改善による可能性があります。


元の回答(2011年4月10日):

しばらく前に、numpyとBLASを使用してpythonで記述された線形代数の計算/アルゴリズムを最適化する必要があったため、異なるnumpy/BLAS構成のベンチマーク/テストを行いました。

具体的にテストしました:

  • ATLASでのナンピー
  • Numpy with GotoBlas2 (1.13)
  • MKLでのNumpy(11.1/073)
  • Numpy with Accelerate Framework(Mac OS X)

2つの異なるベンチマークを実行しました。

  1. サイズの異なる行列の単純な内積
  2. 見つけることができるベンチマークスイート こちら

私の結果は次のとおりです。

機械

Linux(MKL、ATLAS、No-MKL、GotoBlas2):

  • [〜#〜] os [〜#〜]:Ubuntu Lucid 10.4 64ビット。
  • [〜#〜] cpu [〜#〜]:2 x 4 Intel(R)Xeon(R)E5504 @ 2.00GHz(8コア)
  • [〜#〜] ram [〜#〜]:24 GB
  • Intel Compiler:11.1/073
  • Scipy:0.8
  • Numpy:1.5

Mac Book Pro(フレームワークの高速化):

  • [〜#〜] os [〜#〜]:Mac OS X Snow Leopard(10.6)
  • [〜#〜] cpu [〜#〜]:1 Intel Core 2 Duo 2.93 Ghz(2コア)
  • [〜#〜] ram [〜#〜]:4 GB
  • Scipy:0.7
  • Numpy:1.3

Macサーバー(フレームワークの高速化):

  • [〜#〜] os [〜#〜]:Mac OS X Snow Leopard Server(10.6)
  • [〜#〜] cpu [〜#〜]:4 X Intel(R)Xeon(R)E5520 @ 2.26 Ghz(8コア)
  • [〜#〜] ram [〜#〜]:4 GB
  • Scipy:0.8
  • Numpy:1.5.1

ドット製品ベンチマーク

コード

import numpy as np
a = np.random.random_sample((size,size))
b = np.random.random_sample((size,size))
%timeit np.dot(a,b)

結果

システム|サイズ= 1000 |サイズ= 2000 |サイズ= 3000 | 
 netlib BLAS | 1350ミリ秒| 10900ミリ秒| 39200ミリ秒| 
 ATLAS(1 CPU)| 314ミリ秒| 2560ミリ秒| 8700ミリ秒| 
 MKL(1 CPU)| 268ミリ秒| 2110ミリ秒| 7120ミリ秒| 
 MKL(2 CPU) 3660ミリ秒| 
 MKL(8 CPU)| 39ミリ秒| 319ミリ秒| 1000ミリ秒| 
 GotoBlas2(1 CPU)| 266ミリ秒| 2100ミリ秒| 7280ミリ秒| 
 GotoBlas2(2 CPU)| 139ミリ秒| 1009ミリ秒| 3690ミリ秒| 
 GotoBlas2(8 CPU)| 54ミリ秒| 389ミリ秒| 1250ミリ秒| 
 Mac OS X(1 CPU)| 143ミリ秒| 1060ミリ秒| 3605ミリ秒| 
 Macサーバー(1 CPU)| 92ミリ秒| 714ミリ秒| 2130ミリ秒| 

Dot product benchmark - chart

ベンチマークスイート

コード
ベンチマークスイートの詳細については、 here を参照してください。

結果

システム|固有値| svd | det | inv |ドット| 
 netlib BLAS | 1688ミリ秒| 13102ミリ秒| 438ミリ秒| 2155ミリ秒| 3522ミリ秒| 
 ATLAS(1 CPU)| 1210ミリ秒| 5897ミリ秒| 170ミリ秒| 560ミリ秒| 893ミリ秒| 
 MKL(1 CPU)| 691ミリ秒| 4475ミリ秒| 141ミリ秒| 450ミリ秒| 736ミリ秒| 
 MKL(2 CPU)| 552ミリ秒| 2718ミリ秒| 96ミリ秒| 267ミリ秒| 423ミリ秒| 
 MKL(8 CPU)| 525ミリ秒| 1679ミリ秒| 60ミリ秒| 137ミリ秒| 197ミリ秒| 
 GotoBlas2(1 CPU)| 2124ミリ秒| 4636ミリ秒| 147ミリ秒| 456ミリ秒| 743ミリ秒| 
 GotoBlas2(2 CPU)| 1560ミリ秒| 3278ミリ秒| 116ミリ秒| 295ミリ秒| 460ミリ秒| 
 GotoBlas2(8 CPU)| 741ミリ秒| 2914ミリ秒| 82ミリ秒| 262ミリ秒| 192ミリ秒| 
 Mac OS X(1 CPU)| 948ミリ秒| 4339ミリ秒| 151ミリ秒| 318ミリ秒| 566ミリ秒| 
 Macサーバー(1 CPU)| 1033ミリ秒| 3645ミリ秒| 99ミリ秒| 232ミリ秒| 342ミリ秒| 

Benchmark suite - chart

Installation

[〜#〜] mkl [〜#〜]のインストールには、完全なIntel Compiler Suiteのインストールが含まれていましたが、これは非常に簡単です。ただし、MKLサポートでnumpyを構成およびコンパイルするいくつかのバグ/問題のために、少し面倒でした。

GotoBlas2は、共有ライブラリとして簡単にコンパイルできる小さなパッケージです。ただし、 バグ があるため、numpyで使用するには、ビルド後に共有ライブラリを再作成する必要があります。
このビルドに加えて、複数のターゲットプラットフォーム用のビルドが何らかの理由で機能しませんでした。そのため、最適化されたlibgoto2.soファイルが必要なプラットフォームごとに。soファイルを作成する必要がありました。

Ubuntuのリポジトリからnumpyをインストールすると、[〜#〜] atlas [〜#〜]を使用するようにnumpyが自動的にインストールおよび構成されます。ソースから[〜#〜] atlas [〜#〜]をインストールするには時間がかかり、追加の手順(fortranなど)が必要になります。

FinkまたはMac PortsでMac OS Xマシンにnumpyをインストールすると、numpyが[〜#〜] atlas [〜#〜を使用するように設定されます]またはAppleのAccelerate Frameworknumpy.core._dotblasファイルでlddを実行するか、numpy.show_config()を呼び出すことで確認できます。

結論

[〜#〜] mkl [〜#〜]が最もよく機能し、その後にGotoBlas2が続きます。
固有値テストでは、GotoBlas2のパフォーマンスは予想よりも驚くほど悪くなっています。なぜそうなのかわからない。
AppleのAccelerateフレームワークは、特に他のBLAS実装と比較して、シングルスレッドモードで非常に優れたパフォーマンスを発揮します。

GotoBlas2[〜#〜] mkl [〜#〜]の両方が、スレッド数に応じて非常にうまくスケーリングします。したがって、複数のスレッドで実行する大きな行列を処理する必要がある場合は、非常に役立ちます。

いずれにせよ、デフォルトのnetlib blas実装を使用しないでください。深刻な計算作業には遅すぎるためです。

また、クラスターにAMDのACMLをインストールしました。パフォーマンスは[〜#〜] mkl [〜#〜]およびGotoBlas2に似ていました。タフな数字はありません。

個人的にはGotoBlas2を使用することをお勧めします。インストールが簡単で、無料だからです。

C++/Cでコーディングする場合は、 Eigen をチェックアウトしてください-MKL/GotoBlas2cases で、非常に簡単です使用する。

105
Ümit

Matrix x Matrix乗算はメモリに制約があるため、同じメモリ階層に追加のコアを追加してもあまり意味がありません。もちろん、Fortran実装に切り替えたときに大幅な高速化が見られる場合、私は間違っているかもしれません。

私の理解では、適切なキャッシングは計算能力よりもこの種の問題にとってはるかに重要だということです。おそらくBLASがあなたのためにこれを行います。

簡単なテストでは、インストールを試すことができます Enthought's pythonディストリビューション。Intelの Math Kernel Library にリンクしています。可能な場合は。

2
MRocklin

MAGMAのことを聞いたことがありますか? GPUおよびマルチコアアーキテクチャ上のマトリックス代数 http://icl.cs.utk.edu/magma/

MAGMAプロジェクトは、LAPACKに似ていますが、異種/ハイブリッドアーキテクチャ向けの高密度線形代数ライブラリを、現在の「マルチコア+ GPU」システムから開発することを目的としています。

1
Lindon