web-dev-qa-db-ja.com

プロファイリングツールを使用できない場合、プログラムのパフォーマンスを最適化するにはどうすればよいですか?

現在、パフォーマンスを改善したいOpenGlプログラムに取り組んでいます。パフォーマンスは大丈夫ですが、強力な専用GPUでは理想的ではありませんが、統合グラフィックス(<10 fps)ではひどいです。通常のプログラム(CPUベース、OpenGlやその他のGPU APIなし)では、プログラムでプロファイラー(おそらくCLionに組み込まれているもの)を実行し、ほとんどの時間が費やされている場所を確認してから、より良いアルゴリズムで作業しますそれらのエリアの場合、またはそのエリアが呼び出される量を減らす方法を見つけます。

OpenGlプログラムでこの手法を使用すると、メインスレッド(最適化したいスレッド)でのプログラムの時間の大部分(約86%)がOpenGlドライバーの.soファイルに費やされていることがわかります。さらに、プログラムの実行中のCPU使用率は非常に低いですが、GPU使用率は95%から100%の間で停止します。これらの情報を総合すると、ボトルネックがGPUにあるため、最適化する必要があることがわかります。

ここで問題が発生します。ただし、プロファイラーを使用して最適化をガイドする通常の手法は、特定のGPUプロファイラーがないと機能しません。そのため、GPU処理時間が費やされている場所を教えてくれるプロファイラーを見つけるために、いくつかの調査を行いました。リモートで使用できるものは何も見つかりませんでした。すべてがWindowsのみ(私はLinuxのみを実行しており、私のプログラムはまだWindowsに移植されていません-ずっと先までは移植されません)、更新されていない、および/またはの予算をはるかに超えていますこのプロジェクトです。

そのため、関連するプロファイラーが存在しない場合、プログラムのパフォーマンスをどのように最適化できますか?問題がどこにあるのかを推測し、そこから最適化しようとしましたが、最適化(錐台カリング)によってGPUの作業が約半分になることが確認できたとしても、違いはありませんでした。良い答えは、Linux上のOpenglに適用できるプロファイリングテクニックを提供するか、プロファイラーなしで機能するテクニックを提供します。

8
john01dav

関連するプロファイラーが存在しない場合、プログラムのパフォーマンスを最適化するにはどうすればよいですか?

コードを自分でプロファイリングする。 GPUのボトルネックを見つけることは特に難しくありません。

OpenGLのバージョンが古いと仮定すると( タイマークエリ は使用できません)、長年人々が行ってきたことを実行します。

レンダリングのボトルネックには3つの基本的な場所があります。CPU(つまり、非効率的なデータ送信)、頂点T&L、およびフラグメントごとの処理です。どちらがボトルネックであるかを判別することは、何かを変更したときにパフォーマンスへの影響を確認するだけの問題です。

たとえば、フラグメントごとの処理がボトルネックであるかどうかを確認する場合は、生成されるフラグメントの数(つまり、画面の解像度)を減らします。画面解像度のピクセル数に対して線形速度でパフォーマンスが向上する場合は、それがボトルネックでした。

頂点処理がボトルネックであるかどうかを知りたい場合は、同じオブジェクトを複数回(次々に)レンダリングします。深度テストがアクティブであり、ブレンドを実行していない場合、フラグメントシェーダーを呼び出す前に、後続のレンダリングからのフラグメントを間引く必要があります。したがって、すべてのオブジェクトを繰り返しレンダリングすることでパフォーマンスが直線的に低下する場合は、頂点処理のボトルネックがあります。

そして、これらのいずれもがボトルネックでない場合、除去のプロセスにより、CPUが問題になります。

タイマークエリにアクセスできる場合は、GPUオペレーションを直接計時できます。特定のステージの時間を計測することはできませんが、GPUコマンドが完了するまでにかかる時間を決定できます。 GPUコマンドが完了してから、CPUスレッドがそれらのコマンドの送信を終了するまでのレイテンシも確認できます。全体として、これらは、GPUがデータを送信するCPUと比較して、GPUがデータを処理するのにかかる時間を知るのに役立ちます。

7
Nicol Bolas