DAXPY、DCOPY、DSCALはやりすぎですか?


8

インテルMKLにリンクすることにより、CGをFORTRANに実装しました。

次のようなステートメントがある場合:(Wikipediaを参照

 p=r; 
 x=x+alpha*p
 r=r-alpha*Ap;

またはQMRの類似のもの(はるかに多い)

v_tld = r;
y = v_tld;
rho = norm( y );
w_tld = r;
z = w_tld;
xi = norm( z ); (and more)

DAXPY、DCOPY、DSCALなどのBLASレベル1実装を使用することには意味がありますか? 私の質問の動機は:

  1. アルゴリズムの実装は2つあります。NormsとMatVecsのみをMKLにリンクしたもの。コピー、スケーリング、追加は、Fortranの組み込み関数と、可能なすべてのサブルーチンがBLASによって実行される別の関数によって行われます。

  2. 私は、BLASより速くなることはできないという考えでした。しかし、Fortranの組み込み関数を使用する私のコードは、BLASレベル1サブルーチンを使用するコードよりも100%高速であることがわかりました(FWIW、これは小さな問題ではありませんでした。 GB RAM)。私は2スレッドで(2コアマシンで)両方を実行ifort QMR.f90 -mklしていましたMKL_DYNAMIC=TRUE

  3. 私がいたSOの質問を BLASの拡張に関するけど、私は自分のコードにBLASレベル1が含まれるようにしようとしたとして、私のコードは遅く、遅くなって続けました。

私は何か間違ったことをしていますか、これは予想されますか?

また、BLASを拡張してy = 2.89*xbyのような自明ではない操作を行うことは理にかなっていDCOPY(n,2.89*x,1,y,1) or even DSCAL then DCOPYますか?


また興味深いのは、パフォーマンスDDOTDNRM2向上させることです。彼らは倍精度の乗算を実行するため、並列に配置すると役立つ可能性があるという事実に起因しました。

補足質問:BLASレベル1操作が実際にパフォーマンスを向上させるかどうかはいつ決定しますか?

追加:現在、私はi3 2.13 GHzラップトップで4 GBのRAMとDebian 64ビットのプロセッサ情報をここで実行しています。しかし、24 GBのRAMを搭載したIntel Xeon 12コアワークステーションでも同様の回答が得られます。


どのハードウェアを実行していますか?
ペドロ

2
BLAS / LAPACKよりも高速なものはないと仮定しないでください。それらは実用性のために最適化されており、必ずしも金メダルを獲得する速度ではありません。速度が必要な場合は、これを試してみてください
Mike Dunlavey、2012

DCOPY(n、2.89 * x、1、y、1)は、望んだことをしません。それは間違いです。必要な機能はDAXPYです。
Jeff

MKL_DYNAMIC = TRUEはパフォーマンスがひどいです。私はこれから利益を得る科学的コードを知りません。これをオフにし、MKL_NUM_THREADS / OMP_NUM_THREADSを使用してスレッド番号を設定し、OMP_SCHEDULE = STATICをオンにします。
Jeff

回答:


6

あなたの目標が本当にできるだけ多くのパフォーマンスを絞ることであるなら、それを覚えておくことは重要です:

  1. (BLAS)ライブラリは、正確なシステム/構成に合わせて調整されていない可能性があります。
  2. ライブラリ開発者は間違いを犯します。

ベンダーが調整したBLASライブラリがデフォルトのアプローチになるはずですが、個々のカーネルを時々見ていて、他の実装の方が速いことに気付いた場合は、必ず他の実装を使用してください。ベクトル組み込み関数の使い方を忘れると、パフォーマンスに大きな違いが生じる可能性があります。

daxpydscalなどの単純なルーチンに対する最善のは、ベクトル組み込み関数を利用する手書きのループである可能性があります。


私は論理的に反論することはできませんが(2)、それがここで適切であるとは思いません。DCOPY、DSCAL、DAXPYを適切に実装するのはほとんど簡単です。そのため、人々が間違いを犯すことはないと思います。問題は、これらの簡単さは、これらの関数がハードウェアの制限に非常に速く到達するため、有効な最適化がほとんどないという事実に由来することです。
Jeff

3

今日のコンパイラの最適化の状態を考えると、私はリニアBLASルーチンで多くのブードゥー教が、ないと思う例えばDAXPYDCOPYDSCAL、お使いのコンパイラがまだしないだろうということ、例えばSSEベクトル化とループ展開。

コードが同じである場合、ルーチンとMKLのBLASの呼び出しとの唯一の違いは、関数呼び出しのオーバーヘッドと、そこでMKLが実行しようとしている追加のマジックです。この場合、コードとMKLのコードの差は、問題やベクトルのサイズに関係なく、一定でなければなりません。

この質問には、この質問の興味深いエコーがありますDAXPY。これも例として使用します。


2

BLAS標準には、実際には、多くの状況で不要な関数引数の正当性に関するいくつかのチェックがあります。のこのリファレンス実装を参照してくださいdaxpy.f。さらに、などの定数INCXは通常、コンパイル時に認識されますが、実装では想定されない場合があります。BLASはクロスコンパイルユニットを呼び出しますが、プログラム全体の最適化をオンにすることなくこれらを最適化できるコンパイラーについては知りません。

  • これの面白い補足として、インテルコンパイラーはBLAS 3マトリックスマトリックス乗算ループを認識し、十分な最適化を有効にして、このコードを同等のxgemm呼び出しに変換します。

DAXPYの条件を削除して、パフォーマンスに影響があるかどうかを確認する実験を実行しましたか?私はそれが真剣に疑っています。
Jeff

いいえ。ただし、純粋なアセンブリコードを記述し、いくつかのプラットフォームのBLASでベンダー提供のDAXPYよりも優れています:)
Aron

1

BLAS1関数は、計算強度が低いために帯域幅が制限されているカーネルのセットを表します。特に、これらのカーネルはメモリアクセスごとにO(1)フロップを実行します。つまり、最新のハードウェアでは、ピークのごく一部で実行され、基本的には何もすることができません。BLAS1の最適な実装では、アライメントをチェックし、FPUベクトル長をモジュロ化して、帯域幅ピークで実行します。これは、計算ピークの5〜10%になる可能性があります。

これらの操作をソースで明示的に記述すると、優れたコンパイラはそれらをすぐに認識し、上記のBLAS1と同等の最適な実装をインライン化します。ただし、コンパイラーはコンテキストについて知っているため、特定の分岐(これらはそれほど重要ではない)と関数呼び出しのオーバーヘッドを回避できるだけでなく、関数呼び出しによってブロックされるコードで高次変換を実行する可能性もあります。不透明なライブラリ。

実際にコードのパフォーマンスに影響しているものを特定するために実行できるさまざまな実験があります。それらはかなり明白なので、ここではそれらをリストしません。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.