科学ソフトウェアはどの程度最適化する必要がありますか?


13

大量の計算リソースを必要とするアプリケーションの場合、科学的結果の提供や合理的な時間での「ブレークスルー」の達成に関して、高性能は重要な要素となります。

ソフトウェア開発者は、アプリケーションの最適化にどれだけの時間と労力を投資すべきですか?使用される主要な基準は何ですか?


科学者が作成するプログラムは、非常に長い時間実行されることがよくあります(シミュレーションなど)。プログラマーの時間とコンピューターの実行時間は同等です。これは、今日の「通常の」プログラマーの仕事とは大きく異なります。コンピューティングの初期のように、シミュレーションを高速化し、より迅速に終了し、ジョブをより速く完了するために、多くの労力(およびプログラマーの時間)を投資する価値があります。
サボルクス

回答:


15

ほとんどの場合、アルゴリズムの改善は、最適化の改善よりも大きな違いをもたらします。アルゴリズムは、低レベルの最適化よりも移植性があります。私のアドバイスは、キャッシュの再利用のためのメモリレイアウトに関する一般的なベストプラクティスに従い、過剰なコピーや通信を回避し、ファイルシステムを適切に処理し、浮動小数点カーネルにベクトル化に十分な粒度を持たせることです。時々、これは「ピーク」の許容できる高い割合に達するのに十分です(この操作の場合)。

重要だと思う操作(またはプロファイリングで重要だとわかる操作)のパフォーマンスモデルを常にスケッチします。次に、パフォーマンスモデルを使用して、高度に調整された実装が提供できるものを推定できます。スピードアップにそれだけの価値があると判断した場合(他の方法と比較して)、最適化を行います。

おそらく最も難しい課題は、APIを変更せずに後で最適化できるように、高レベルで重要な(多くのコードがこれらの選択に依存するという意味で)インターフェイスとデータ構造を設計することです。特定の最適化と一般的なガイドラインとは対照的に、私はこれを経験することを除いて教える方法を知りません。パフォーマンスに敏感なオープンソースソフトウェアを使用すると便利です。APIの決定と同様に、問題の領域を理解することが重要です。


1
つい最近、時間と空間のO(n ^ 2)であったアルゴリズムを1つのO(n log n ) 両者に。それは別の依存関係およびいくつかの追加の複雑さ、時にはそれの価値がある...意味断っておくが
dmckee ---元司会者の子猫

1
(何かに関連する)スピードアップ要因は、あなたが比較したものを明確に参照する価値はあまりありません。不適切なアルゴリズムに基づいた不適切な実装と比較して変更する場合、大きな相対ゲインを期待することは明らかに不合理ではありません。
アランP. Engsig-Karup

1
@Allan:単一の変更から取得するのに10,000の係数がありましたが、明らかに不適切な実装でした。前のコードは、時間の複雑さだけでなく、不要なスペースによっても傷つけられました。キャッシュのパフォーマンスはひどいものでした。しかし、それがポイントですよね?
dmckee ---元モデレーター子猫

8

「最適化」をどのように定義しますか?より優れたアルゴリズムや計算モデルの開発から、手作業で調整されたアセンブラーの使用まで、あらゆる範囲があります。

私の意見と経験では、例えば、基礎となるコンピューターアーキテクチャに最適なアルゴリズムを選択するなど、簡単に実行できる成果は中間にあります。アルゴリズムは必ずしも新しいものである必要はなく、基礎となるアーキテクチャの理解は必ずしも非常に具体的である必要はありません。たとえば、

  • アーキテクチャがSIMDをサポートしていることがわかっている場合は、短いベクトルの観点から操作を記述できるように計算を再構築し、
  • アーキテクチャがマルチコアコンピューターであることがわかっている場合は、計算タスクを互いに干渉しない個々のサブタスクに分解し、それらを並行して実行してみてください(サブタスクのDAGを考えてください) 、
  • 基盤となるアーキテクチャにGPUがある場合、ロックステップでデータを行進するスレッドのグループとして計算を再定式化する方法を考えてください。
  • 等...

上記のすべての機能(SIMD、並列処理、GPUなど)は、低レベルの知識がなくてもアクセスできますが、それらをすぐに活用できるアルゴリズムでのみ利点を提供します。


4

私はこれまでに出されたすべての答えに同意します...コード最適化のもう1つの見落とされている側面、品質期待に対処したいだけです。

通常、コード最適化の問題は、ユーザーがますます大きな問題を解決しようとして、コードがユーザーのニーズ/期待を満たすには不十分な場合に発生します。コード最適化に投資すべき時間は、この期待に応える需要に依存します。競争上の優位性に対する重要なニーズがある場合は、かなりの時間を投資する価値があることは確かです(例えば、ホットトピックに関する研究を他の人より先に仕上げて公開するなど)。

もちろん、どれだけの時間を投資すべきかは、どれだけ速くする必要があるか、そしてコードをどれだけ移植可能にするかによって異なります。多くの場合、これら2つのニーズは互いに矛盾しており、最適化を開始する前にどちらが重要かを判断する必要があります。移植性が高いほど、コード(アルゴリズム/データ構造)の高度な設計変更に依存する必要があります。コードの実行速度を上げるには、特定のマシンに固有の低レベルの最適化(コード/コンパイラ/ランタイムの最適化など)でチューニングする必要があります。


4

実行速度を上げるために非常に多くの人月を費やす(そして常に神話的である:-))(コスト)分析を行う必要があります。このソフトウェアが何回使用されるか、そして何人の人がゲインを推定できるかを把握する必要があります。

経験則は、いつものように、有名な80/20ルールです。ある時点では、実行時間の数パーセント(またはそれ以下)を獲得するためにますます多くの時間を費やすために、それ以上加算されません。しかし、分析する必要があります。

そして、私は心から上記のポスターに同意します:APIがよく考えられているので、多くの変更を必要とせず、コードが移植可能で保守可能であることを確認してください(あなたが書いたアルゴリズムと、 10年前に最適化)。また、適切なプログラミング手法と標準ライブラリを使用してください。誰かがあなたのアプリケーションにとって最も効率的なアルゴリズムについて既に考えている可能性は合理的です。

ドナルド・クヌースを引用する:「早すぎる最適化はすべての悪の根源です」。したがって、コードのプロファイルを作成しますが、すぐにではありません。


パレート原理(80/20)ルールについて言及していますか?もしそうなら、スローダウンの80%を生み出すコードの20%に最適化の努力を集中すべきだということですか?または、20%の高速化しか期待できない場合、最適化するだけの価値がないということですか?
ポール

いいえ、正確に80/20ではなく、一種の原則としてのみ使用しました。しばらくすると、ほんの数パーセントしか得られないほどの努力を払うことになり、それ以上の努力の価値はなくなります。
GertVdE

3

追加のアドバイス:

  1. 作業プログラムの最適化を行う前に、コードの整合性を維持するのに役立つテストケースのセットがあることを確認してください。間違った結果をより早く取得しても意味がありません。
  2. 最適化によりコードが読みにくくなる場合は、少なくともコメントの形式で元のバージョンを保持しますが、コンパイル時および実行時に選択される代替バージョンとしてはより適切です。最適化のニーズは、問題やマシンが進化するにつれて変化する可能性があり、元のコードは、5年後に行う最適化のより良い開始点になる可能性があります。
  3. 最適化されたバージョンの影響が最小限であることが判明したが、コードの可読性、汎用性、または安定性が低下した場合は、元のバージョンに戻ります。あなたが得るよりも多くを失う。
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.