2

他社の非常に経験豊富なプログラマーが、パイプライン最適化を含む、特定のCPUを対象とした低レベルのコード最適化のヒントについて教えてくれました。ターゲティングハードウェア用。

順不同で投機的な実行の存在で、私はちょうどこの種の低レベルのことをするためのポイントがあるのだろうか?私たちは主にハイパフォーマンスコンピューティングに携わっているので、最適化を行うために1つの非常に特定のCPUタイプに焦点を当てることができますが、この特定の最適化を行うポイントがあるかどうかはわかりません。 ?この種の最適化のコード例はありますか?どうもありがとう!

4

3 に答える 3

6

まず、高レベルのコードとアルゴリズムが最適化されていれば、コンパイラは通常、コードを十分に (つまり、十分に) 最適化するので、これについて心配する必要はありません。一般に、手動による最適化は、定量化して追跡できる実際のパフォーマンスの問題があるという確固たる証拠がある場合にのみ行う必要があります。

とはいえ、物事を改善することは常に可能です。時には少し、時には大幅に。

ハイパフォーマンス コンピューティング ゲームに参加している場合、この種の最適化は理にかなっているかもしれません。実行できるあらゆる種類の「トリック」がありますが、気弱な人向けではなく、真の専門家に任せるのが最善です。

このトピックについて本当に知りたい場合は、Agner Fog の Web サイトを読むことから始めることをお勧めします。

于 2013-02-02T00:38:03.277 に答える
3

パイプラインの最適化により、プログラムのパフォーマンスが向上します。

分岐とジャンプにより、プロセッサが命令パイプラインを強制的にリロードする場合があり、これには時間がかかります。今回は、データ処理命令に専念できます。

パイプラインを最適化するためのプラットフォームに依存しない方法:

  1. 支店数を減らす。
  2. ブール演算を使用
  3. 命令の条件付き実行を可能にするコードを設定します。
  4. ループを展開します。
  5. ループのコンテンツを短くします (ロードせずにプロセッサのキャッシュに収まる)。

編集 1: その他の最適化

  1. 機能と要件を排除してコードを削減します。
  2. 設計を確認して最適化します。
  3. より効率的な実装のために実装を確認します。
  4. 他のすべての最適化によってパフォーマンスがほとんど改善されない場合にのみ、アセンブリ言語に戻します。時間の 80% で実行されるコードのみを最適化します。プロファイリングでわかる。

編集 2: データの最適化

データを整理することで、パフォーマンスを向上させることもできます。Web で「データ ドリブン デザイン」または「パフォーマンス データの最適化」を検索します。

1 つの考えとしては、最も頻繁に使用されるデータを近くに配置し、最終的にプロセッサのデータ キャッシュに収める必要があります。これにより、プロセッサがデータ キャッシュをリロードする頻度が減ります。

もう 1 つの最適化は、データを (レジスタに) ロードし、データを操作してから、すべてのデータをメモリに書き戻すことです。ここでの考え方は、プロセッサがデータ (またはレジスタ) を処理する前に、プロセッサのデータ キャッシュ ロード回路をトリガーすることです。

可能であれば、プロセッサのキャッシュの 1 つの「行」に収まるようにデータを整理してください。シーケンシャル ロケーションは、ランダム アクセス ロケーションよりも時間がかかりません。

于 2013-02-02T00:32:31.717 に答える
1

パイプラインでの実行を「助ける」対「妨げる」ものは常にありますが、高度に特殊化されていないほとんどの汎用コードの場合、コンパイルされたコードのパフォーマンスは、得られる最高のものとほぼ同じであると予想されます。プロセッサのモデルごとに高度に専門化されたコードは必要ありません。すべてのマシンが同じ (または少数の同様の) プロセッサ モデルを使用している制御されたシステムがあり、時間の 99% がこの特定の機能に費やされていることがわかっている場合、その特定の機能を最適化して、より効率的にします。

あなたの場合、それは HPC であり、実行中のプロセッサ用に最適化される低レベル コード (行列乗算など) の一部を手書きすることが有益な場合があります。ただし、これにはある程度のプロセッサの理解が必要です。そのため、そのプロセッサ モデルの最適化ガイドを調べて、可能であれば、そのプロセッサで以前に作業したことのある人に相談する必要があります。

あなたが見ていることのいくつかは、「依存関係を登録する」です - x = c + d を計算するために c = a + b の結果が必要です - したがって、これらを他の有用な作業と分離しようとします。 x の計算は、c = a + b の計算によって遅れることはありません。

キャッシュのプリフェッチと、一般的にキャッシュがどのように使用されるかを考慮することも有用です。結果として得られる 1MB の配列を保存するときに、100 命令後に必要な有用なキャッシュ データを追い出すことはありません。数秒が多くのプロセッサ時間に値する場合があります。

コンパイラが独自の最適化でシャッフルすることを決定した場合、これらのことを制御するのは(より)難しいため、手書きのアセンブラがほぼ唯一の方法です。

于 2013-02-02T00:32:38.950 に答える