マルチCPUシステムで微分方程式を解くFortranプログラムのパフォーマンスを測定するように依頼されました。私の雇用主は私がFLOP/s(1秒あたりの浮動演算数)を測定し、その結果をベンチマーク( [〜#〜] linpack [〜#〜] )と比較することを主張していますが、それがその方法であるとは確信していませんFLOPとは誰にも説明できないからです。
FLOPとは何かについて調査を行い、かなり矛盾する答えを得ました。私が得た最も人気のある答えの1つは、「1 FLOP =加算および乗算演算」でした。本当?もしそうなら、再び、物理的に、それは正確にはどういう意味ですか?
私が最終的に使用する方法が何であれ、それはスケーラブルでなければなりません。一部のバージョンのコードは、数百万の未知数を含むシステムを解決し、実行に数日かかります。
私の場合、パフォーマンスを測定する他の効果的な方法は何ですか?
それが何を測定するかを正確に理解している限り、それはパフォーマンスのかなりまともな尺度です。
FLOPSは、名前が1秒あたりの浮動小数点操作数を示しているため、FLOPを構成する要素はCPUによって異なる場合があります。 (たとえば、一部のCPUは1つの演算として加算と乗算を実行できますが、他のCPUは実行できません)。つまり、パフォーマンスの指標としては、ハードウェアにかなり近いということです。つまり、1)特定のアーキテクチャで理想的なFLOPSを計算するには、ハードウェアを知っている必要があり、アルゴリズムと実装を知って、実際に構成されている浮動小数点演算の数を把握します。
いずれにしても、CPUの使用状況を調べるのに便利なツールです。 FLOPSでのCPUの理論上のピークパフォーマンスがわかっている場合は、CPUの浮動小数点ユニットを効率的に使用できます。これは、多くの場合、効率的に利用するのが難しいものの1つです。 FLOPS CPUの能力がある)の30%を実行するプログラムには、最適化の余地があります。70%で実行するプログラムは、基本的なアルゴリズムを変更しない限り、おそらくはるかに効率的になることはありません。 。あなたのような数学を多用するアルゴリズムの場合、これはパフォーマンスを測定するためのほぼ標準的な方法です。プログラムの実行にかかる時間を単純に測定できますが、CPUによって大きく異なります。ただし、プログラムのCPU使用率が50%の場合(ピークと比較してFLOPSカウント)、これはやや一定の値です(根本的に異なるCPUアーキテクチャ間でも変わりますが、実行時間よりもずっと一貫しています)。
しかし、「私のCPUはX GFLOPSに対応していて、実際にはその20%のスループットしか達成していない」ということを知ることはvery高性能ソフトウェアの貴重な情報。それは、浮動小数点演算以外の何かotherがあなたを後押しし、FPユニットが効率的に機能するのを妨げていることを意味します。そしてFP単位は作業の大部分を構成するため、ソフトウェアに問題があることを意味します。
「私のプログラムはX分で実行されます」は簡単に測定できます。それが受け入れられないと感じた場合は、「30%を切り落とせるかどうか疑問に思います」と進むことはできますが、そうすることはできませんknowそれが可能である場合、実行されている作業の正確な量、およびCPUがピーク時に実行できる正確な量を計算しない限り。 CPUが1秒あたりの命令を根本的に実行できるかどうかさえわからない場合、これを最適化するためにどのくらいの時間を費やしたいですか?
CPUのFPユニットが効率的に使用されないようにする、FP opsの間に依存関係が多すぎる、または分岐が多すぎるなどの防止策があると、効率的なスケジューリング。そしてそれが実装を妨げているものである場合、あなたはそれを知る必要があります。あなたは、「私はFP可能なスループットなので、コードの他の部分が明らかに妨げているFP CPUが命令を発行する準備ができているときに命令が使用できない。 ".
パフォーマンスを測定する他の方法が必要なのはなぜですか? FLOPS上司から求められた数を数えるだけで何が問題ですか?;)
細かい点をいくつか追加したいと思います。
divisionは特別です。ほとんどのプロセッサは1サイクルで加算、比較、または乗算を実行できるため、これらはすべて1フロップとしてカウントされます。ただし、分割には常に時間がかかります。どれくらい長くプロセッサに依存しますが、HPCコミュニティには、1部門を4フロップとして数えるという事実上の標準があります。
プロセッサに融合乗算-加算命令があり、乗算と加算を1つの命令で実行する場合(通常はA + = B * C)、2つの演算としてカウントされます。
single-precisionフロップとdouble-precision flopsの区別には常に注意してください。非常に多くの単精度ギガフロップを処理できるプロセッサは、その多くの倍精度ギガフロップのごく一部しか処理できない場合があります。 AMD AthlonおよびPhenomプロセッサは、通常、単精度の半分の倍精度フロップを実行できます。 ATI Firestreamプロセッサは、通常、単精度の1/5の倍精度フロップを実行できます。誰かがあなたにプロセッサまたはソフトウェアパッケージを販売しようとしていて、彼らがどちらも言わずに単にフロップを見積もっている場合、あなたはそれらについてそれを呼ぶべきです。
メガフロップ、ギガフロップ、テラフロップなどの用語が一般的に使用されています。これらは、係数10、not 1024を参照します。たとえば、1メガフロップ= 1,000,000フロップ/秒は1,048,576ではありません。ディスクドライブのサイズと同じように、これにはいくつかの混乱があります。
昔の質問、人気があるとしても正確ではないIMO。
「FLOP」は浮動小数点演算です。 「FLOPS」は次の2つのいずれかを意味します。
文脈から明確ではない場合、これらのうちどれを意味するかは、前者を「FLOP」、後者を「FLOP/s」と書くことによって明確になることがよくあります。
FLOPは、整数演算、論理演算、ビット演算、メモリ演算、分岐など、他の種類のCPU演算と区別するためにいわゆる異なるコスト(「異なる時間の長さ」を参照)が関連付けられている操作。
「FLOPカウント」の実践は、FLOPが比較的多くのCPUサイクルを必要とする比較的高価な科学計算のごく初期にさかのぼります。たとえば、80387の数値演算コプロセッサでは、1回の乗算に300サイクル程度かかりました。これは、パイプライン処理が行われる前、およびCPUクロック速度とメモリ速度の違いが実際に明らかになる前の時点でした。メモリ操作には1〜2サイクルしかかからず、分岐(「意思決定」)も同様に安価でした。当時、1度のFLOPを排除して、数十回のメモリアクセスを優先できれば、利益が得られました。ダースのブランチを支持して単一のFLOPを排除できれば、あなたは利益を得ました。したがって、過去には、FLOPを数えることは意味がありました。FLOPは実行時間を大幅に支配しているため、FLOPは非常に個別であったためです。他の種類の操作に比べて高価です。
最近では、状況は逆転しています。 FLOPは非常に安価になりました—最新のIntelコアは、サイクルごとに約2つのFLOPを実行できます(除算は比較的高価ですが)—メモリアクセスとブランチは比較的はるかに高価です:L1キャッシュヒットのコストはおそらく3または4サイクルで、メインメモリからのフェッチのコストは150〜200です。この反転を考えると、メモリアクセスを優先してFLOPを削除してもゲインが発生することはありません。実際、それはありそうもないことです。同様に、FLOPを冗長にする場合でも、実行するかどうかを決定するよりも、FLOPを「実行する」だけの方が安上がりです。これは、25年前の状況とは正反対です。
残念ながら、アルゴリズム的なメリットの絶対的な測定基準としてのブラインドFLOPカウントの慣行は、販売期限を過ぎても続いています。 現代の科学計算は、メモリ帯域幅管理の詳細—実行ユニットを保持しようとする FLOPには常にデータが供給されます— FLOPの数を減らすことよりも。 [〜#〜] linpack [〜#〜]への参照(これは[〜#〜] lapack [〜#〜]によって本質的に廃止されました) 20年前)は、あなたの雇用主はおそらく非常に古い学校に所属しており、パフォーマンスの期待を確立することはFLOPのカウントだけの問題ではないという事実を内面化していないのではないかと思います。 2倍のFLOPを実行するソルバーは、メモリアクセスパターンとデータレイアウトがはるかに優れている場合、他のソルバーよりも20倍速くなる可能性があります。
これらすべての結果は、計算集約型ソフトウェアのパフォーマンス評価が、以前よりもはるかに複雑になったことです。 FLOPが安価になったという事実は、メモリ操作と分岐のコストの膨大な変動性によって非常に複雑になります。 アルゴリズムの評価に関しては、単純なFLOPカウントでは、全体的なパフォーマンスの期待値はもはや通知されません。
おそらく、パフォーマンスの期待と評価について考えるより良い方法は、いわゆる ルーフラインモデル によって提供されます。これは完全とはほど遠いですが、あなたを作るという利点があります浮動小数点とメモリ帯域幅の問題のトレードオフについて同時に考え、パフォーマンス測定とパフォーマンス期待値の比較を可能にする、より有益で洞察に満ちた「2Dピクチャー」を提供します。
一見の価値があります。
「結果をベンチマークと比較」して何をしますか?
FLOPSはあなたが必要とすることを意味します
1)作業単位ごとのFLOP。
2)その作業単位の時間。
いくつかのループを1,000回繰り返す入力ファイルがあるとします。ループは便利な作業単位です。 1,000回実行されます。 1時間ほどかかります。
ループには、いくつかの加算と乗算、およびいくつかの除算と平方根があります。加算、乗算、除算をカウントできます。これをソースでカウントして、+、*、および/を探すことができます。コンパイラーからのアセンブラー言語の出力を見つけ、そこでカウントすることもできます。別の番号が表示される場合があります。どちらが正しいですか?上司にお尋ねください。
平方根を数えることはできますが、乗算と加算に関してそれが実際に何を行うかはわかりません。したがって、平方根の所要時間を把握するには、ベンチマークの乗算と平方根の比較などを行う必要があります。
これで、ループのFLOPSがわかりました。また、1,000回実行する時間もわかりました。1秒あたりFLOPSがわかります。
次に、LINPACKを見ると、速度が遅いことがわかります。それで?プログラムはLINPACKではなく、LINPACKよりも低速です。あなたのコードが遅くなる確率は本当に良いです。あなたのコードが同じ年数のLINPACKで書かれて最適化されていなければ、遅くなるでしょう。
ここに他の部分があります。プロセッサには、いくつかの定義済みのFLOPSさまざまなベンチマークに対する評価があります。アルゴリズムはこれらのベンチマークの1つではないため、ベンチマークに達していません。これは悪いことですか?これは、ベンチマーク?
実行可能な結果はどうなるでしょうか?
一部のベンチマークコードベースに対する測定は、アルゴリズムがベンチマークアルゴリズムではないことを伝えるだけです。それはあなたが違っているというのは当然の結論です。通常は遅くなります。
明らかに、LINPACKに対して測定した結果は、(a)異なるため、(b)最適化する必要があります。
yourselfに対して行われた場合にのみ、測定は本当に価値があります。架空の命令の組み合わせではなく、独自の命令の組み合わせ。自分のパフォーマンスを測定します。変える。自分と比較して、パフォーマンスが良くなるか悪くなるかを確認してください。
FLOPSは関係ありません。重要なのは、作業単位あたりの時間です。ハードウェア設計者が期待したベンチマークを実行していないため、ハードウェアの設計パラメーターを一致させることは決してありません。
LINPACKは関係ありません。重要なのは、コードベースと、パフォーマンスを変更するために行う変更です。
私はそれをできるだけ速くするようにしようと思います、そしてそれは特に回避できる関数呼び出しがある場合、それが時間を費やしている場所を見つける必要があります。
実行中に数回中断するだけで、何が行われているかを確認するという簡単な方法でこれを行います。ここに私が見つけるものの種類があります:
ほとんどの場合、それは導関数やヤコビアンを計算している最中です。この時間の多くは、exp()
、log()
、sqrt()
などの数学関数呼び出しに入ることができます。多くの場合、これらは同じ引数で繰り返され、メモ化できます。 (大幅なスピードアップ。)
積分許容誤差が必要以上に厳しいため、多くの時間は、導関数の計算に何度も費やされます。 (もっと早く)
方程式が硬いと考えられるために陰的積分アルゴリズム(DLSODE Gearなど)が使用されている場合、それらはそうではなく、Runge-Kuttaのようなものが使用される可能性があります。 (DVERK)。 (より速く)
おそらく、モデルが線形(DGPADM)の場合、行列指数アルゴリズムを使用できます。これは、パフォーマンスと精度の両方で大きな勝利であり、剛性に影響されません。 (かなり速い)
コールスタックの上位では、同じ積分がわずかに異なるパラメーターで繰り返し実行され、それらのパラメーターに関するソリューションの前方または中央差分勾配を決定している可能性があります。微分方程式自体が微分可能である場合、それらの勾配を分析的に取得したり、感度方程式で方程式を拡張したりすることが可能です。これは、はるかに高速であるだけでなく、はるかに正確であり、スタックをさらに高くスピードアップできます。
スタックの各レベルは、最適化するものを見つける機会として見ることができ、スピードアップはさらに複雑になります。次に、multi-cpuに移動すると、それが並列化可能であると想定すると、独自の乗算係数が提供されます。
FLOPsに戻ります。あなたはしようとすることができます最大化FLOPs / second
、しかしminimzeFLOPs / run
、スタックのすべてのレベルで最適化する。いずれにせよ測定だけではほとんど何もわかりません。
A FLOPSは、あなたが言ったように、1秒あたりの浮動小数点演算です。例として、演算(2つの値の加算、減算、乗算、または除算など)にちょうど1秒かかる場合結果を返す)、パフォーマンスは単純に1 FLOPSです。最近のCPUは数GigaFLOPS、つまり1秒あたり数十億の浮動小数点演算を簡単に実現します。
あなたの雇用主は正しいです。
Fortranプログラム(またはその他のプログラム、btw)の有効性を測定する唯一の方法は、標準のベンチマーク(存在する場合)に対してテストすることです。
また、FLOPについては、「1秒あたりの浮動小数点演算」を表しています。Wikipediaの definition を参照してください。
FLOPSを測定することは非常に役に立ちません。
FLOPS達成数は、アルゴリズムがCPUをどれだけビジー状態にしているかを示しますが、アルゴリズム自体のパフォーマンスはわかりません。
プロセッサが同じ数のFLOPSを実行する原因となる2つの異なるアルゴリズムがありますが、1つは半分の時間で目的の結果を提供します。
時間単位(つまり、アルゴリズムの目的)ごとに解かれる微分方程式の数など、はるかに「より高いレベル」の統計を見たほうがいいと思います。
一方、達成されたFLOPSの数を測定することは、CPUをどれだけビジー状態にしているかがわかるので、アルゴリズムを改善するのに役立ちます。