質問

マルチCPUシステムで微分方程式を解くFortranプログラムのパフォーマンスを測定するように頼まれました。私の雇用主は、FLOP / s(フローティング操作/秒)を測定し、その結果をベンチマーク( LINPACK )しかし、だれも私にFLOPが何であるかを説明することができないからです。

FLOPとは何かについて調査を行いましたが、かなり矛盾した答えが得られました。私が得た最も人気のある答えの1つは、「1 FLOP =加算および乗算演算」でした。本当?もしそうなら、再び、物理的に、それはどういう意味ですか?

最終的にどの方法を使用するにしても、スケーラブルでなければなりません。コードの一部のバージョンは、数百万の未知数を持つシステムを解決し、実行に数日かかります。

私の場合のパフォーマンスを測定する他の、効果的な方法は何ですか(私のケースの概要は、数百のCPUで数日間にわたって何度も何度も何度も算術計算を行うFortranコードです)

役に立ちましたか?

解決

それが測定するものを正確に理解している限り、パフォーマンスのかなり適切な測定値です。

FLOPSは、名前がFLoating point OPerations per Secondを意味するため、正確にFLOPを構成するものはCPUによって異なる場合があります。 (たとえば、一部のCPUは加算と乗算を1つの演算として実行できますが、他のCPUは実行できません)。つまり、パフォーマンスの尺度として、ハードウェアにかなり近いことを意味します。つまり、1)特定のアーキテクチャで理想的なFLOPSを計算するにはハードウェアを知る必要があり、アルゴリズムと実装を知って方法を把握する必要があります。実際に構成される多くの浮動小数点演算。

いずれの場合でも、CPUの使用率を調べるのに役立つツールです。 CPUの理論的なFLOPSのピークパフォーマンスがわかっている場合は、CPUの浮動小数点ユニットをどれだけ効率的に使用できるかを知ることができます。 CPUが可能なFLOPSの30%を実行するプログラムには、最適化の余地があります。基本的なアルゴリズムを変更しない限り、70%で実行されるものはおそらくそれほど効率的ではありません。あなたのような数学が重いアルゴリズムの場合、これはパフォーマンスを測定するためのほとんどの標準的な方法です。プログラムの実行にかかる時間を簡単に測定できますが、これはCPUによって大きく異なります。ただし、プログラムのCPU使用率が50%(ピークFLOPSカウントに対して)の場合、これはやや一定の値です(根本的に異なるCPUアーキテクチャ間でも変わりますが、実行時間よりもずっと一貫しています)。

しかし、「私のCPUはX GFLOPSに対応しており、実際にスループットの20%しか達成していない」ことを知っています。高性能ソフトウェアでは非常に貴重な情報です。これは、浮動小数点演算以外の何かがを妨げているため、FPユニットが効率的に動作しないことを意味します。 FPユニットは作業の大部分を構成するため、ソフトウェアに問題があることを意味します。

「私のプログラムはX分で実行されます」を測定するのは簡単です。もしそれが受け入れられないと感じたら、「30%を切り落とすことができるかどうか」と思いますが、あなたは< em>それが可能であるかどうか、正確にどれだけの作業が行われているか、そしてピーク時にCPUが何ができるかを正確に判断しない限り、可能です。 CPUが基本的に毎秒これ以上の命令を実行できるかどうかさえわからない場合、これを最適化するのにどれくらいの時間を費やしますか?

CPUのFPユニットが効率的に使用されるのを防ぐのは非常に簡単です。FPop間の依存関係が多すぎるか、ブランチが多すぎるか、同様の方法で効率的なスケジューリングができません。それが実装の妨げとなっている場合、それを知る必要があります 。 「可能なFPスループットが得られないので、CPUが発行する準備ができたときにコードの他の部分がFP命令を使用できないことを明らかにする必要があります」

パフォーマンスを測定するために他の方法が必要なのはなぜですか?上司からの要求に応じてFLOPSカウントを計算するだけで何が問題になりますか? ;)

他のヒント

さらに細かい点をいくつか追加したい:

  • 分割は特別です。ほとんどのプロセッサは1サイクルで加算、比較、または乗算を実行できるため、これらはすべて1フロップとしてカウントされます。ただし、除算には常に時間がかかります。プロセッサに依存する時間はどれくらいかかりますが、HPCコミュニティには1部門を4フロップとしてカウントするための事実上の標準があります。

  • 1つの命令(通常はA + = B * C)で乗算と加算を行う fused Multiply-Add 命令がプロセッサにあり、2つの操作としてカウントされる場合。

  • 単精度フロップと倍精度フロップを区別する場合は常に注意してください。非常に多くの単精度ギガフロップが可能なプロセッサは、その多くの倍精度ギガフロップのごく一部しか使用できない場合があります。 AMD AthlonおよびPhenomプロセッサは、通常、単精度の半分の倍精度のフロップを実行できます。 ATI Firestreamプロセッサは通常、単精度の1/5の倍精度のフロップを実行できます。誰かがあなたにプロセッサまたはソフトウェアパッケージを販売しようとしていて、彼らがどちらを言わずに単にフロップを引用するのであれば、あなたはそれを呼び出すべきです。

  • メガフロップス、ギガフロップス、テラフロップスなどの用語が一般的に使用されています。これらは 1000 の要素を指し、 1024ではありません。たとえば、1メガフロップ= 1,048,576ではなく1,000,000フロップ/秒。ディスクドライブのサイズと同様に、これには多少の混乱があります。

&quot;結果をベンチマークと比較する&quot;そして何をしますか?

FLOPSは必要なことを意味します

1)作業単位ごとのフロップ。

2)その作業単位の時間。

あるループで1,000回の反復を行う入力ファイルがあるとします。ループは便利な作業単位です。 1,000回実行されます。 1時間かかります。

ループには、いくつかの加算と乗算、およびいくつかの除算と平方根があります。加算、乗算、除算をカウントできます。ソースでこれを数え、+、*、/を探します。コンパイラーからのアセンブラー言語の出力を見つけて、そこでカウントすることもできます。異なる番号が表示される場合があります。どちらが正しいですか?上司に聞いてください。

平方根を数えることはできますが、乗算と加算の点でそれが実際に何をするのかわかりません。そのため、平方根にかかる時間を把握するには、ベンチマーク乗算と平方根のような処理を行う必要があります。

これでループのフロップがわかりました。そして、1,000回実行する時間を知っています。 1秒あたりのFLOPSを知っています。

次にLINPACKを見ると、速度が遅いことがわかります。それで?あなたのプログラムはLINPACKではなく、LINPACKよりも遅いです。コードが遅くなる可能性は非常に高いです。コードがLINPACKと同じ年数で記述および最適化されていない限り、遅くなります。

これは他の部分です。プロセッサには、さまざまなベンチマークに対して定義されたFLOPS評価があります。アルゴリズムはこれらのベンチマークの1つではないため、ベンチマークに達しません。これは悪いですか?または、これはベンチマークではないことの明らかな結果ですか?

実行可能な結果はどうなりますか?

一部のベンチマークコードベースに対する測定では、アルゴリズムがベンチマークアルゴリズムではないことがわかります。あなたは違うだろうというのは当然の結論です。通常は遅くなります。

明らかに、LINPACKに対して測定した結果は、(a)異なるため、(b)最適化する必要があります。

測定は、自分自身に対して行われた場合にのみ本当に価値があります。架空の命令ミックスではなく、独自の命令ミックス。自分のパフォーマンスを測定します。変える。自分と比べてパフォーマンスが良くなるか悪くなるかを確認してください。

FLOPSは重要ではありません。重要なのは、作業単位あたりの時間です。ハードウェア設計者が期待したベンチマークを実行していないため、ハードウェアの設計パラメーターと一致することはありません。

LINPACKは関係ありません。重要なのは、コードベースとパフォーマンスを変更するために行っている変更です。

IMOの古い質問で、人気があったとしても正確ではない古い回答。

「FLOP」は、浮動小数点演算です。 「FLOPS」は、次の2つのいずれかを意味します。

  • 「FLOP」の単純な複数形(つまり、「操作 X は50 FLOPsを要する」)
  • 第1の意味でのFLOPの rate (つまり、毎秒の浮動小数点演算)

文脈から明らかでない場合、これらのどちらを意味するかは、前者を「FLOPs」、後者を「FLOP / s」と書くことで明確にされることがよくあります。

FLOPは、整数演算、論理演算、ビット単位演算、メモリ演算、分岐演算など、コストが異なる他の種類のCPU演算と区別するために呼ばれます(読み取り) 「異なる時間をかける」)それらに関連付けられています。

「FLOPカウント」の実践は、FLOPが比較的多くの場合非常に高価で、それぞれ多くのCPUサイクルを使用していた科学計算の非常に初期の時代にまで遡ります。たとえば、80387数学コプロセッサは、1回の乗算に300サイクルのようなものを取りました。これは、パイプライン処理の前であり、CPUクロック速度とメモリ速度の差が実際に広がる前のことでした。メモリ操作は1〜2サイクルしかかからず、分岐(「意思決定」)も同様に安価でした。当時、1ダースのメモリアクセスを優先して単一のFLOPを削除できれば、利益が得られました。単一のFLOPを削除して1ダースのブランチを選べば、利益を得ました。そのため、以前は、FLOPが実行時間を大幅に支配していたため、FLOPをカウントし、メモリ参照とブランチについてあまり心配する必要はありませんでした。 >

最近、状況は逆転しました。 FLOPは非常に安価になりました。最新のIntel core はサイクルあたり約2 FLOPを実行できます(ただし、除算は比較的高価のままです)。また、メモリアクセスとブランチは比較的高価です。L1キャッシュヒットコストはおそらく3または4サイクル、メインメモリからのフェッチは150〜200です。この反転を考えると、メモリアクセスを優先してFLOPを削除しても結果が得られるということはなくなりました。実際、それはまずありません。同様に、FLOPを実行するかどうかを決定するよりも、冗長である場合でも、FLOPを「実行する」方が安価なことがよくあります。これは25年前の状況のほぼ完全な反対です。

残念なことに、アルゴリズムのメリットの絶対的な指標としてのブラインドFLOPカウントの慣行は、賞味期限を過ぎても持続しました。 最新の科学計算では、FLOPの数を減らすことよりも、FLOPに常にデータを供給している実行ユニットに行うを維持しようとすることで、メモリ帯域幅管理がはるかに重要です。 LINPACK (これは20年前に LAPACK によって本質的に廃止されました)への参照は、あなたの雇用主がおそらく事実を内在化していない非常に古い学校であると疑います。パフォーマンスの期待値を確立することは、FLOPのカウントだけではありません。はるかに好ましいメモリアクセスパターンとデータレイアウトを備えている場合、2倍のFLOPを実行するソルバーは、他のFLOPよりも20倍高速です。

これらすべての結果は、計算量の多いソフトウェアのパフォーマンス評価が、以前よりもはるかに複雑になったことです。 FLOPが安価になったという事実は、メモリ操作とブランチのコストの変動性によって非常に複雑になっています。 アルゴリズムの評価に関しては、単純なFLOPカウントは単に全体的なパフォーマンス期待を通知しません

FLOPSは、あなたが言ったように、1秒あたりの浮動小数点演算です。たとえば、1つの操作(2つの値の加算、減算、乗算、除算、結果の返還など)に1秒かかる場合、パフォーマンスは1 FLOPSになります。最近のCPUは、数GigaFLOPS、つまり毎秒数十億の浮動小数点演算を簡単に達成できます。

できるだけ速く実行しようとするだけです。特に、回避できる関数呼び出しがある場合は、どこで時間を費やしているのかを見つける必要があります。

これは、実行中に数回中断するだけで、実行中の動作を確認する簡単な方法で行います。私が見つけたものは次のとおりです。

  • 多くの場合、微分および/またはヤコビアンの計算プロセスにあります。この時間の大部分は、 exp() log()、および sqrt()などの数学関数呼び出しに使用できます。多くの場合、これらは同じ引数で繰り返され、メモ化することができます。 (大幅な高速化。)

  • 積分の許容誤差が必要以上に厳しいため、微分の計算に多くの時間が費やされます。 (高速)

  • 方程式が硬いと考えられているために暗黙的な積分アルゴリズム(DLSODE Gearなど)が使用されている場合、偶然ではない可能性があり、Runge-Kuttaのようなものを使用できます。 (DVERK)。 (さらに高速)

  • モデルが線形(DGPADM)の場合、おそらく行列指数アルゴリズムを使用できます。これは、パフォーマンスと精度の両方で大きなメリットがあり、剛性の影響を受けません。 (より速く)

  • コールスタックを上げると、わずかに異なるパラメーターで同じ統合が繰り返し実行され、それらのパラメーターに関するソリューションの前方または中央差分勾配が決定される可能性があります。微分方程式自体が微分可能である場合、それらの勾配を分析的に取得するか、感度方程式を使用して方程式を拡張することができます。これははるかに高速であるだけでなく、はるかに正確であり、スタックをさらに高速化できます。

最適化するものを見つける機会としてスタックの各レベルを見ることができ、スピードアップはさらに複雑になります。それから、マルチCPUに行くとき、それが並列化可能であると仮定すると、それはそれ自身の乗算係数を提供するはずです。

FLOPに戻ります。 最大化 FLOPs /秒を試みることもできますが、最小化 FLOPs /実行することも非常に便利です。 、スタックのすべてのレベルで最適化する。いずれにせよ、それらを測定するだけではほとんど何もわかりません。

あなたの雇用主は正しい。
Fortranプログラム(またはその他のプログラムbtw)の有効性を測定する唯一の方法は、標準ベンチマークが存在する場合、それをテストすることです。

そして、FLOPについては、「毎秒の浮動小数点演算」の略です。 -ウィキペディアの定義を参照してください。

FLOPSの測定は非常に役立つとは思いません。

達成されたFLOPSの数は、アルゴリズムがCPUを保持している忙しさを示しますが、アルゴリズム自体のパフォーマンスはわかりません。

プロセッサに同じ数のFLOPSを実行させる2つの異なるアルゴリズムがありますが、一方は半分の時間で目的の結果を提供します。

単位時間あたりに解く微分方程式の数(つまり、結局のところ、アルゴリズムの目的)など、はるかに「高いレベル」の統計を見た方が良いと思います。

一方、達成されたFLOPSの数を測定すると、CPUを保持している忙しさを示すため、アルゴリズムを改善するのに役立ちます。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top