45

何かがシングル スレッド プログラムの実行に必要な時間の 10 倍の時間を要している場合、そのプログラムに対してプロファイラーを実行できます。また、「一時停止」ボタンで停止することもでき、それが何をしているかを正確に見ることができます.

本来より 10% 遅くても、何度も停止すると、やがて不要なことを繰り返すようになります。通常、問題は実際には必要のないスタックの途中にある関数呼び出しです。これは問題を測定しませんが、確かに見つけます。

編集:反対意見は、ほとんどの場合、サンプルを1つだけ取ることを前提としています。真剣に考えるなら、10 をとってください。40% のような無駄の割合を引き起こしているコード行は、平均して、サンプルのその部分のスタックに表示されます。(シングル スレッド コードの) ボトルネックは、そこから隠れることはできません。

編集:私の言いたいことを示すために、多くの反対意見は「十分なサンプルがないので、あなたが見るものは完全に偽物である可能性があります」という形をとっています - 偶然についての漠然とした考え. しかし、ルーティン内にいるだけでなく、ルーティンがアクティブであるだけでなく、何らかの認識可能な説明が 30% の時間有効である場合、特定のサンプルでそれが見られる確率は 30% です。

次に、サンプルが 10 個だけ取得されたとします。10 サンプルで問題が見られる回数は二項分布に従い、問題が0 回見られる確率は .028 です。1回見る確率は.121です。2回の確率は.233、3回の確率は.267で、その後落ちます。2 回未満で表示される確率は .028 + .121 = .139 なので、2 回以上表示される確率は 1 - .139 = .861 となります。原則として、2 つ以上のサンプルで修正できるものが見つかった場合は、修正する価値があります。

この場合、10 個のサンプルで見られる確率は 86% です。あなたがそれを見ていない 14% にいる場合は、見られるまでサンプルを増やしてください。(サンプル数を20に増やすと、2回以上見る確率が99%以上になります。)ですから、正確に測定したわけではありませんが、正確に見つけたので、それを理解することが重要です。プログラムカウンターではなく、データの状態に関係するものなど、プロファイラーが実際に見つけることができないものである可能性があります。

4

17 に答える 17

53

Java サーバーでは、2 ~ 3 回のクイックCtrl実行Breaksを実行して、実行中のすべてのスレッドの 2 ~ 3 個のスレッドダンプを取得するのが、常に巧妙な方法です。すべてのスレッドが「ある」場所を調べるだけで、パフォーマンスの問題がどこにあるかを非常に迅速に特定できます。

この手法は、私が知っている他のどの手法よりも多くのパフォーマンスの問題を 2 分間で明らかにすることができます。

于 2008-11-25T12:23:13.517 に答える
34

うまくいくこともあれば、完全に間違った答えを返すこともあります。プロファイラーは、正しい答えを見つけるというよりもはるかに優れた記録を持っており、通常はより速くそこにたどり着きます。

于 2008-11-05T19:52:34.607 に答える
27

これを手動で行うことは、実際には「迅速」または「効果的」とは言えませんが、これを自動的に行うプロファイリング ツールがいくつかあります。統計プロファイリングとも呼ばれます。

于 2008-11-05T19:51:56.930 に答える
15

コールスタック サンプリングは、プロファイリングに非常に役立つ手法です。特に、さまざまな場所で時間を費やしている可能性がある大規模で複雑なコードベースを調べる場合に役立ちます。これには、インタラクティブ性にとって重要な実時間で CPU の使用率を測定できるという利点があり、各サンプルでコールスタックを取得すると、関数が呼び出された理由を確認できます。私はそれをよく使用しますが、Luke StackwalkerOProfileなどの自動化ツールや、ハードウェア ベンダーが提供するさまざまなものを使用しています。

私が自分の仕事で手動のサンプリングよりも自動化されたツールを好む理由は、統計的検出力です。実行時間の 40% を占める関数が 1 つある場合、手動で 10 個のサンプルを取得しても問題ありません。これは、平均して 4 つのサンプルが取得され、常に少なくとも 1 つのサンプルが取得されるためです。ただし、数百のリーフ関数があり、実行時間の 1.5% を超えるものがないフラットなプロファイルがある場合は、より多くのサンプルが必要です。

さまざまな種類の魚がいる湖があるとします。湖の魚の 40% がサケ (および 60% が「その他」) である場合、10 匹の魚を捕まえるだけで、湖にサケがたくさんいることがわかります。しかし、何百もの異なる種類の魚がいて、それぞれの種類がそれぞれ 1% 以下である場合、「この湖は 0.8% のサーモンと 0.6% のトラウトです」と言えるようになるには、10 匹以上の魚を釣る必要があります。 ."

同様に、私が取り組んでいるゲームでは、いくつかの主要なシステムがあり、それぞれが数百の異なるエンティティで数十の関数を呼び出しており、これらすべてが 1 秒間に 60 回行われています。これらの関数の時間は、一般的な操作 ( などmalloc) に集中するものもありますが、ほとんどはそうではありません。

トランク関数を見て、「衝突に 10% の時間を費やしている」ことがわかりますが、これはあまり役に立ちません。衝突の場所を正確に知る必要があるため、どの関数をスクイーズするかがわかります。「衝突を減らす」だけでは、特に機能を捨てることを意味する場合は、これまでのところしか得られません。「魔法のミサイルが非常に速く移動し、多くのセルに触れるため、octreeの狭いフェーズでキャッシュ ミスに平均 600 マイクロ秒/フレームを費やしている」ことを知りたいです。そうすれば、正確な修正を追跡できます。より良い木か、より遅いミサイルのどちらかです。

たとえば に 20% の大きな塊がある場合、手動サンプリングは問題ありstricmpませんが、プロファイルではそうではありません。代わりに、フレームの 0.6% からフレームの 0.4% まで、何百もの関数を取得する必要があります。毎秒 300 回呼び出される 50 μs 関数ごとに 10 μs を削る必要があります。そのような精度を得るには、より多くのサンプルが必要です。

しかし、本質的に Luke Stackwalker が行うことは、あなたが説明することです: ミリ秒ごとにプログラムを停止し、コールスタックを記録します (正確な命令とIPの行番号を含む)。一部のプログラムでは、有用なプロファイリングを行うために数万のサンプルが必要です。

(もちろん、これについては以前に話しましたが、これは議論を要約するのに適した場所だと思いました。)

于 2011-11-28T00:46:14.527 に答える
10

プログラマーが実際に行うことと、他の人に勧めることには違いがあります。

私は実際にこの方法を使用している多くのプログラマー(私自身を含む)を知っています。パフォーマンスの問題の最も明白なものを見つけるのに本当に役立つだけですが、それは迅速で汚く、機能します。

しかし、すべての警告を説明するには時間がかかりすぎるため、他のプログラマーにそうするように実際に指示することはしません。この方法に基づいて不正確な結論を出すのは非常に簡単であり、まったく機能しない領域がたくさんあります。(たとえば、そのメソッドは、ユーザー入力によってトリガーされるコードを明らかにしません)。

したがって、法廷で嘘発見器を使用するのと同じように、または「goto」ステートメントを使用するのと同じように、それらすべてに用途がありますが、使用することはお勧めしません。

于 2008-11-05T20:09:39.343 に答える
10

両側の宗教的なトーンに驚かされます。

プロファイリングは素晴らしいものであり、実行できればより洗練され正確になります。できない場合もありますが、信頼できるバックアップがあると便利です。一時停止のテクニックは、電動工具が遠すぎる場合やバッテリーが切れた場合に使用する手動ドライバーのようなものです。

ここに短い実話があります。アプリケーション (一種のバッチ処理タスク) は、本番環境で 6 か月間正常に動作していましたが、「遅すぎる」という理由で突然、オペレーターが開発者に電話をかけました。彼らは、本番環境でサンプリング プロファイラーをアタッチすることを許可しません! すでにインストールされているツールで作業する必要があります。プロダクション プロセスを停止することなく、 Process Explorerを使用するだけで (オペレータがマシンにインストール済み)、スレッドのスタックのスナップショットを確認できました。スタックの一番上をちらっと見て、Enter キーで閉じ、別のマウス クリックで別のスナップショットを取得できます。1 秒ごとにサンプルを簡単に取得できます。

スタックの最上位がデータベース クライアント ライブラリ DLL (データベースを待機中) にあるか、別のシステム DLL (システム操作を待機中) にあるか、または実際にアプリケーション自体。この場合、私の記憶が正しければ、10 回中 8 回は、アプリケーションがシステム DLL ファイル呼び出しでネットワーク ファイルの読み取りまたは書き込みを行っていることにすぐに気付きました。案の定、最近の「アップグレード」により、ファイル共有のパフォーマンス特性が変更されました。アプリケーションが実稼働環境で何を行っているかを確認するための迅速かつ汚い (システム管理者が承認した) アプローチがなければ、問題を修正するよりも、問題の測定にはるかに多くの時間を費やしていたでしょう。

一方、パフォーマンス要件が「十分に良い」を超えて実際に限界を押し上げる場合、プロファイラーが不可欠になります。これにより、密接に結び付いたトップ 10 または 20 のすべてのホット スポットからサイクルを削ることができます。プロジェクト中に中程度のパフォーマンス要件を維持しようとしているだけでも、測定とテストに役立つ適切なツールを揃えることができ、自動化されたテスト プロセスにそれらを統合することさえできれば、非常に役立ちます。

しかし、電源が切れていて (いわば) 電池が切れている場合、その手動ドライバーの使い方を知っていると便利です。

つまり、直接的な答えは次のとおりです。プログラムを停止することから何を学べるかを知っておいてください。ただし、精密ツールを恐れる必要はありません。最も重要なことは、どのジョブがどのツールを必要とするかを知ることです。

于 2009-10-28T07:13:11.103 に答える
8

「なぜそれがよく知られていないのか」という質問をすると。そうすれば、答えは主観的なものになります。おそらく、それがよく知られていない理由は、プロファイリングが現在の問題の解決策ではなく、長期的な解決策を提供するためです。マルチスレッドアプリケーションには効果的ではなく、レンダリングにかなりの時間を費やすゲームなどのアプリケーションには効果的ではありません。

さらに、シングルスレッドアプリケーションでは、最も多くの実行時間を消費すると予想されるメソッドがあり、他のすべてのメソッドの実行時間を短縮したい場合、どのセカンダリメソッドに注力するかを決定するのは難しくなります。最初に。

プロファイリングのプロセスは、機能する可能性があり、機能する許容可能な方法ですが、プロファイリングはより多くの情報を提供し、より詳細なパフォーマンスの向上と回帰を示すという利点があります。

適切にインストルメント化されたコードがある場合は、特定のメソッドの長さだけでなく、それ以上のことを調べることができます。あなたはすべての方法を見ることができます。

プロファイリングあり:

  • 次に、変更のたびにシナリオを再実行して、パフォーマンスの向上/低下の程度を判断できます。

  • さまざまなハードウェア構成でコードをプロファイリングして、実稼働ハードウェアで十分かどうかを判断できます。

  • 負荷およびストレステストのシナリオでコードをプロファイリングして、情報の量がパフォーマンスにどのように影響するかを判断できます

  • ジュニア開発者は、ビーチやパブ、またはその両方にいる間、6か月以内にコードのプロファイルを再作成できるため、コードへの変更の影響を簡単に視覚化できます。ビーチパブ、ftw。

エンタープライズコードは、長期間の組織にメリットがあるため、常にある程度のプロファイリングが必要であるため、プロファイリングの重要性が高くなります。コードが重要であるほど、プロファイリングとテストを行います。

あなたのアプローチは有効であり、もう1つの項目は開発者のツールボックスです。プロファイリングがそれを上回っています。

于 2008-11-06T14:16:04.660 に答える
8

サンプリングプロファイラーは、次の場合にのみ役立ちます。

  1. 少数のスレッドでランタイムを監視しています。できれば1つ。
  2. 各スレッドの呼び出しスタックの深さは比較的小さいです(サンプルを収集する際の信じられないほどのオーバーヘッドを減らすため)。
  3. あなたは壁時計時間だけを気にし、他のメーターやリソースのボトルネックは気にしません。
  4. 管理および監視の目的でコードをインストルメントしていません(したがって、スタックダンプ要求)
  5. スタックフレームを削除することは、固有のコスト(呼び出し先を除く)が実質的にゼロであるかどうかに関係なく、効果的なパフォーマンス改善戦略であると誤って信じています。
  6. ソフトウェアパフォーマンスエンジニアリングを日常業務に適用する方法をわざわざ学ぶことはできません。
  7. ...。
于 2009-07-27T21:42:01.577 に答える
8

「デバッグ」モードでプログラムの実行中に一時停止ボタンを押すと、パフォーマンスの最適化を実行するための適切なデータが提供されない場合があります。率直に言って、これはプロファイリングの大雑把な形式です。

プロファイラーの使用を避ける必要がある場合は、ロガーを使用し、スローダウン係数を適用して実際の問題がどこにあるかを「推測」することをお勧めします。ただし、プロファイラーは、推測を行うための優れたツールです。

デバッグ モードで一時停止ボタンを押しても、アプリケーションの動作を正確に把握できない理由は、デバッガーがアプリケーションの特定の部分を遅くする追加の実行可能コードを導入するためです。デバッグ環境でのアプリケーションのスローダウンの考えられる理由については、 Mike Stall のブログ投稿を参照できます。この投稿は、ブレークポイントが多すぎる、例外オブジェクトの作成、最適化されていないコードなどの特定の理由を明らかにしています。最適化されていないコードに関する部分は重要です。「デバッグ」モードでは、多くの最適化が行われます (通常、コードのインライン化と再実行)。これにより、デバッグ ホスト (コードを実行するプロセス) と IDE がコード実行を同期できるようになります。したがって、「デバッグ」モードで一時停止を繰り返し押すのは悪い考えかもしれません。

于 2008-11-23T02:55:08.157 に答える
7

これらは、メソッドで有用な結果を得るために使用している簡単な例である必要があります。あなたの「迅速で効果的な」方法でまともな結果が得られたであろうプロファイリングが(どんな方法でも)有用だったプロジェクトを私は考えることができません。一部のアプリケーションの開始と停止にかかる時間は、すでに「クイック」の主張に疑問を投げかけています。

繰り返しますが、重要なプログラムでは、あなたが提唱する方法は役に立ちません。

編集:「なぜそれがよく知られていないのか」について?

私の経験では、コードレビューは質の悪いコードとアルゴリズムを避け、プロファイリングはこれらも見つけます。あなたが素晴らしい方法を続けたいのなら-しかし私はほとんどの専門家コミュニティにとってこれは試してみるべきことのリストのはるか下にあると思うので、それは時間の良い使い方として決して前向きな強化を得ることはありません。

小さなサンプルセットではかなり不正確であるように思われ、大きなサンプルセットを取得するには、他の有用なアクティビティに費やしたほうがよい多くの時間がかかります。

于 2008-11-06T14:16:38.713 に答える
7

スタック トレース スナップショットでは、アプリケーションのストロボスコープ X 線のみを表示できます。プロファイラーが提供する可能性のある、より蓄積された知識が必要になる場合があります。

秘訣は、自分のツールをよく知り、目の前の仕事に最適なものを選択することです。

于 2009-10-17T09:21:10.667 に答える
5

プログラムが本番環境にあり、同時にクライアントや同僚が有料で使用している場合はどうなるでしょうか。プロファイラーを使用すると、干渉することなく観察できます (もちろん、ハイゼンベルグの原理に従って少しヒットするため)。

プロファイリングは、より豊富で詳細な正確なレポートを提供することもできます。これは長期的にはより速くなります。

于 2008-11-05T19:53:34.137 に答える
4

私は何年も前にCommodore 64 BASICでこの方法を使用しました。それがどれほどうまく機能するかは驚くべきことです。

于 2008-11-06T23:05:27.057 に答える
4

EDIT 2008/11/25: わかりました。Vineet の応答により、ここで何が問題なのかがようやくわかりました。遅いよりはましです。

どういうわけか、パフォーマンスの問題はパフォーマンスを測定することによって発見されるという考えが、その土地で緩みました。それは目的と手段を混同しています。どういうわけか、プログラム全体をずっと前にシングルステップすることでこれを回避しました。私はそれを人間の速度まで遅くしたことで自分を責めませんでした. 間違ったことや不必要なことをしていないかどうかを確認しようとしていました。それがソフトウェアを高速化する方法です。不要な操作を見つけて削除します。

最近では、1 回のステップ実行に我慢できる人はいませんが、次善の策は、無作為にいくつかのサイクルを選んで、その理由を尋ねることです。(それは、コール スタックがよく教えてくれることです。) それらのかなりの割合に正当な理由がない場合は、それについて何かをすることができます。

最近は、スレッド化や非同期化などで難しくなっていますが、それが私がソフトウェアチューニングする方法です - 不要なサイクルを見つけることによって。どれだけ速いかを見るのではなく、最後にそれを行います。


コール スタックをサンプリングしても間違った答えが得られない理由と、多くのサンプルが必要ない理由は次のとおりです。

対象の間隔中、プログラムが必要以上に時間がかかっている場合、サンプリングしていない場合でも、コール スタックは継続的に存在します。

  • 命令 I がその時間の端数 P(I) のコール スタック上にある場合、それをプログラムから削除することができれば、それを正確に節約できます。これが明らかでない場合は、少し考えてみてください。

命令が N のうち、M = 2 以上のサンプルに現れる場合、その P(I) はおよそ M/N であり、明らかに重要です。

命令を見逃す唯一の方法は、命令がコール スタックにないときにすべてのサンプルを魔法のように計ることです。わずかな時間しか存在しないという単純な事実が、プローブにさらされる原因です。

したがって、パフォーマンス チューニングのプロセスは、コール スタックの複数のサンプルを調べて頭を上げる命令 (主に関数呼び出し命令) を選択するという単純な問題です。それらは森の中の背の高い木です。

コール グラフ、関数にかかる時間、関数が呼び出される回数、または再帰を気にする必要がないことに注意してください。

私はプロファイラーではなく、難読化に反対しています。それらは多くの統計を提供しますが、ほとんどは P(I) を提供せず、ほとんどのユーザーはそれが重要であることを認識していません。

フォレストやツリーについて話すことはできますが、コードを変更することで修正できるパフォーマンスの問題については、命令、特に P(I) が高い命令を変更する必要があります。したがって、できればシャーロック・ホームズをプレイせずに、それらがどこにあるかを知る必要があります。スタック サンプリングは、それらがどこにあるかを正確に示します。

この手法は、マルチスレッド、イベント駆動型、または運用システムで採用するのが困難です。そこで、プロファイラーが P(I) を報告してくれれば、本当に役に立ちます。

于 2008-11-05T20:00:11.657 に答える
4

コードのステップ実行は、核心的な詳細とトラブルシューティング アルゴリズムを確認するのに最適です。それは、木を間近で見て、樹皮と枝の各静脈を個別にたどるようなものです。

プロファイリングを使用すると、全体像を把握し、問題点をすばやく特定できます。たとえば、一歩下がって森全体を見て、最も高い木に気付くことができます。関数呼び出しを実行時間の長さで並べ替えることで、問題のある領域をすばやく特定できます。

于 2008-11-05T20:38:30.673 に答える
3

私は通常、タイムスライスをオーバーランしていたリアルタイムプログラムで使用しました。毎秒60回実行する必要のあるコードを手動で停止して再起動することはできません。

また、自分が作成したコンパイラのボトルネックを追跡するためにも使用しました。このようなプログラムを手動で中断しようとは思わないでしょう。なぜなら、ボトルネックが発生している場所で中断しているのか、OSがボトルネックに戻った直後の場所で中断しているのかを実際に知る方法がないからです。やめろ。また、主要なボトルネックが何もできないものであるが、システム内の他のすべての大きなボトルネックを取り除きたい場合はどうでしょうか。どのボトルネックを最初に攻撃するか、それらがすべてどこにあるかについての適切なデータがない場合、およびそれぞれの相対的な影響をどのように優先しますか?

于 2008-11-06T14:51:04.120 に答える
3

プログラムが大きくなればなるほど、プロファイラーはより便利になります。何千もの条件分岐を含むプログラムを最適化する必要がある場合、プロファイラーは不可欠です。テスト データの最大のサンプルをフィードし、それが完了したら、プロファイリング データを Excel にインポートします。次に、実際のデータに対してホット スポットの可能性が高いという仮定を確認します。いつも驚きがあります。

于 2008-11-23T00:45:37.577 に答える