フロップカウントによるアルゴリズム分析は時代遅れですか?


43

私の数値解析コースでは、問題のサイズに対して、必要な浮動小数点演算(フロップ)の数を数えることにより、アルゴリズムの効率を分析することを学びました。たとえば、数値線形代数に関するTrefethen&Bauのテキストには、フロップカウントの3Dに見える写真さえあります。

キャッシュにないものをフェッチするためのメモリレイテンシは、フロップのコストよりもはるかに大きいため、「フロップは無料」と言うのが流行しています。しかし、少なくとも数値解析コースでは、フロップを数えることを生徒に教えています。代わりに、メモリアクセスをカウントするように教える必要がありますか?新しい教科書を書く必要がありますか?または、メモリアクセスがマシン固有であり、時間を費やすことができませんか?フロップまたはメモリアクセスがボトルネックであるかどうかに関して、長期的な傾向はどうなりますか?

注:以下の回答のいくつかは、「実装を強烈に書き換えて、数フロップを節約するか、キャッシュのパフォーマンスを向上させるべきですか?」しかし、私が求めているのは、「算術演算またはメモリアクセスの観点からアルゴリズムの複雑さを推定する方が便利ですか?」という行に沿ったものです。


1
> 「算術演算またはメモリアクセスの観点からアルゴリズムの複雑さを推定する方が便利ですか?」。実用的な観点から、組み込みシステムはメモリ帯域幅ではなくFPU速度によって制限されます。したがって、HPCの基準でフロップカウントが廃止されたと見なされたとしても、他のコミュニティでは依然として実用的です。
ダミアン14年

回答:


31

βFmaxBmaxFmaxβ>BmaxBmaxβ>Fmax

メモリアクセスのカウントは必須だと思いますが、次のことも考慮する必要があります。

  • 必要なローカルメモリの量

  • 並行性の可能性

その後、最新のハードウェアのアルゴリズムの分析を開始できます。


3
β

2
デビッドは8年前にやっています
マットネプリー

3
さて、(いつものように)より良い、より複雑なモデルがあります。しかし、このモデルはマシンに依存する答えを提供します。最初の分析として使用することを生徒に何を教える必要がありますか?
デビッドケッチャソン

3
ポイントは、アルゴリズムがそうであるように、マシンが単一の数、ピークフロップとピーク帯域幅の比率に削減されたことです。これは簡単です。計算モデルがなければ、複雑さの見積もりは役に立たず、これは最も単純で現実的なものです。
マットネプリー

1
あなたは問題を誤解していると思います。大きな負荷を運ぶことができる光トランスポートがすでにあります。問題は、チップ上でそれを取得しています。あなたは非常に多くのワイヤと最高のクロックレートしか持っていません。光トランスポートは、光チップでこの問題を軽減するだけです。
マットネプリー

22

O(N4)O(N)O(NlogN)O(N2)

より広い観点から、アルゴリズムのパフォーマンスの分析は「包括的」でなければならないと思います。実際のHPC開発者およびユーザーになるように人々に教える場合、彼らは現実世界でのプログラミングのコストを理解する必要があります。私たちが持っている抽象的な分析モデルは、プログラマーの時間を考慮していません。フロップカウントとアルゴリズムの効率だけでなく、「解決までの合計時間」の観点から考える必要があります。数百万の計算を実行することを計画している場合を除き、ジョブあたり1秒のコンピューター時間を節約するルーチンを書き換えるために3〜4日プログラマーを費やすことはほとんど意味がありません。同様に、1〜2時間の計算時間を節約するための数日間の投資は、すぐに報われます。その新しいアルゴリズムは素晴らしいかもしれませんが、


7
O(NlogN)O(N2)

2
O(NlogN)O(N2)

9

他の人が指摘したように、答えはもちろんボトルネックがCPU帯域幅かメモリ帯域幅かによって異なります。任意のサイズのデータ​​セットで機能する多くのアルゴリズムでは、データセットがCPUキャッシュに収まらないため、ボトルネックは通常メモリ帯域幅です。

さらに、Knuthは、メモリアクセス分析は、おそらく最新のCPUパイプラインと分岐予測の複雑さに比べて(キャッシュへの配慮を考慮した場合でも)比較的単純であるため、時の試練に耐える可能性が高いと述べています。

Knuthは、BDDを分析する際にTAOCPのVolume 4Aで用語gigamemsを使用します。彼が以前のボリュームでそれを使用しているかどうかはわかりません。彼は、2010年の年次クリスマスツリーレクチャーで時の試練に耐えることについて前述のコメントをしました。

興味深いことに、あなたは間違ったことをやっているメモリの操作に基づいても、分析のパフォーマンスデータがすべて一度に物理RAMに収まらない場合には遊びに来て、このようなVM圧力などの要素がある簡単なよう常にではないことを示しています。


8

アルゴリズムのコストをどのように決定するかは、使用する科学計算の「レベル」と、検討する問題の(狭いまたは広い)クラスに依存します。

キャッシュの最適化について考える場合、これは明らかに、たとえばBLASや類似のライブラリのような数値線形代数パッケージの実装により関連しています。したがって、これは低レベルの最適化に属し、特定の問題に対する固定アルゴリズムがあり、入力に十分な制約がある場合は問題ありません。たとえば、行列が十分にスパースであると約束されている場合、共役勾配反復の高速実装にキャッシュ最適化が関連する場合があります。

一方、問題のクラスが広ければ広いほど、実際のコンピューティングで予測できることは少なくなります(たとえば、CG実装の入力行列が実際にどの程度まばらになるかわからないなど)。プログラムが実行されるはずのマシンのクラスが広いほど、キャッシュアーキテクチャを予測できなくなります。

さらに、高レベルの科学計算では、問題の構造を変更する方が適切かもしれません。たとえば、線形連立方程式の適切な前提条件を見つけることに時間を費やす場合、この種の最適化は通常、反復回数が大幅に削減されるため、低レベルの最適化よりも優れています。

結論として、キャッシュの最適化は、並列性とFLOPの漸近数の削減によって最適化するものが残っていない場合にのみ役立ちます。

理論的なコンピューターサイエンスの姿勢を適応させることは賢明だと思います。最終的に、アルゴリズムの漸近的複雑さを改善することは、既存のコード行の微最適化よりも多くの利益をもたらします。したがって、FLOPのカウントが依然として優先されます。


「キャッシュの最適化は、並列処理とFLOPの漸近的数の削減によって最適化するものが残っていない場合にのみ役立ちます」。同意しません。大きな数の大きな式を計算する場合は、各数のすべてのステップよりも、すべての数で一度に1つのステップを実行することをお勧めします。両方のFLOPSの数は同じですが、メモリアクセスの方が優れています。キャッシュに収まるように束のサイズを選択した場合(またはコンパイラーがそれを行う)ボーナス。これは、numexprがPythonで行うことです:github.com/pydata/numexpr
Davidmh

6

私はいつも、フロップ、メモリアクセス、またはあなたが持っているものを数えることについて考えることさえ拒否しました。それは1960年代のコンセプトで、あなたがやったことはほとんど与えられていましたが、アルゴリズムの最適化まではあなたがやったことだけでした。Jacobi反復のガウス消去法を使用して、均一なxyzメッシュで有限要素問題を解くことを考えてください。

これで、これを最適化して数フロップを節約し、実行時間を10%増やすことができます。または、マルチグリッドメソッドと最適なブロック前提条件を実装して、実行時に10倍にすることを検討できます。これは、生徒が行うように訓練する必要があるものです。より複雑な外部アルゴリズムが、より良い内部アルゴリズムを見つけようとするときに得られるものを考えてください。上司(キーズ)には、MHD計算の進捗状況に関するこれらのスライドがあり、この点をかなり明確にしています。


実際、私は低レベルの最適化ではなく、あなたが提案するような高レベルの思考について尋ねていました。マルチグリッドと前提条件が代替よりも速いかどうかを判断するために、どのメトリックを使用する必要がありますか?
デビッドケッチャソン

数十行から数千行のコードを実行する複雑なアルゴリズムの場合、FLOPSやその他の命令をカウントする方法を手動でカウントする方法はわかりません。たとえば、AMGアルゴリズムの分析および構築フェーズがどれほど複雑かを考えてください。これらのアルゴリズムには非常に多くの部分があり、それらはすべて実際のデータに依存しているため、操作の数を予測することはできません。
ヴォルフガングバンガース

1
最初はあなたが何をしていたかを誤解したと思いますが、あなたの主張にはまだ賛成できません。「外部アルゴリズム」は、漸近的な複雑さを念頭に置いて設計することができます(そして私は主張するべきです)。確かに、2次アルゴリズムから線形に近いアルゴリズムへのドロップは、せいぜい10%の実行時間の短縮につながるとは主張しません。まだ、フロップやメモリ操作を通してよりも漸近的な複雑さを定量化する他の方法はありますか?
ジャックポールソン

7
アルゴリズムに対するこの「手を投げる」アプローチはくだらないと思います。一次コストだけを見て、モデルを単純化して扱いやすいようにすることで分析を単純化する必要がありますが、MGやCholeskyのようなものは複雑すぎて分析できないと言うのはまったく間違っています。
マットネプリー

1
しかし、カウントするすべてのFLOPが、ハイパースレッドプロセッサ、キャッシュ、低速RAM、マルチスカラープロセッサ、および自動ベクトル化に起因するいくつかの遅延層に隠れている場合、MGまたはコレスキーを分析することはどういう意味ですか?私が指摘しているのは、5〜10倍以内であれば、タイミングを調整しないとアルゴリズムの実行時間を予測できないということです。これは、このFLOPカウントを開始した50年代と60年代に完全に異なっていました。
ウルフギャングバンガース

1

はい、廃止されました。フロップやその他の方法によるアルゴリズム分析は、問題の規模を考慮するときに、マシンの抽象的なモデルと同じくらい有用です。実際のパフォーマンスは実装とハードウェアの両方に依存し、後者の抽象モデルの現実への適用性は時間とともに低下しています。たとえば、分子動力学などの複雑なアルゴリズムの実装をさらに並列化すると、さまざまな側面がさまざまなハードウェアでレート制限になり、アルゴリズム分析は観測とは関係ありません。ある意味では、唯一の重要なことは、問題のハードウェアタイプでのアルゴリズムの実装のパフォーマンスを測定することです。

そのような抽象化は学習ツールとして有用ですか?はい、教育に使用される多くのモデルのように、それらはモデルの制限の理解と並んで配置されている限り有用です。古典的な力学は、小さな距離や大きな速度のスケールでは機能しないことを理解している限りは問題ありません...


-1

質問に実際に答えているわけではありませんが、考慮すべき別の変数をさらに追加します。考慮すべきことは、プログラミング言語の機能です。たとえば、Python sortは、他の優れたプロパティの中でも特に設計されているTimsortアルゴリズムを使用して、比較の数を最小限に抑えます。これは、Pythonオブジェクトでは遅くなる可能性があります。一方、C ++での2つのフロートの比較は非常に高速ですが、それらのスワップはよりコストがかかるため、他のアルゴリズムを使用します。

他の例としては、動的メモリ割り当て(Pythonリストでは簡単、実行時と開発者の両方の時間で高速.append())、対FORTRANまたはCがあります。参照Pythonは速くFORTRANを超えています。


これは本当ですが、あなたが言うように、質問には答えません。別のトピックです。
デビッドケッチャソン14年

さて、適切な分析では、どのアルゴリズムを実装するかを決定するときに考慮する必要があります。
Davidmh
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.