2016-07-29 16 views
0

私はマルチスレッドのC++アプリケーションのプロファイリングにVisual Studioを使用しています。 私がSamplingメソッドについて読んだことから、特定の間隔でプロセッサがどの機能が実行されているかを調べることが分かります。マルチスレッドコードのプロファイリングサンプリングの仕組み

マルチスレッドコードの処理方法が不思議です。 2つ以上の関数が異なるコア上の異なるスレッドで同時に実行される可能性があります。その場合、両方の機能のサンプリング方法インクリメントカウンタはありますか?私はこれが実際に起こっていると信じています。

これは実際にそれが困難なプロファイリングレポートのうちの洞察を導出することができます。収集されたサンプルの数が最も多い関数は、ワーカースレッド上で実行されている場合、別のコア(メインスレッド以外)で実行されている可能性があり、アプリケーションのパフォーマンスにまったく影響を与えません。しかし、作業を実行するためにメインスレッドを切り替える場合は、パフォーマンスに目に見える影響があります。

マルチスレッドコードをプロファイルする良い方法はありますか?

+1

はい。スレッドがあなたのアプリのパフォーマンスに影響しないならば、あなたはそれを間違っているし、まったく使っていないほうが良いでしょう。 UIのフリーズを防ぐ非同期性の必要性をモジュロにしますが、それは並行性ではありません。なぜマルチスレッドプログラムが泥を吸うのかを知るには、別の種類のツール[並行処理アナライザ]が必要です(https://msdn.microsoft.com/en-us/library/dd537632.aspx?f=255&MSPPError=-2147217396) 。 –

答えて

1

サンプリング機能の実行時に、プロファイラは通常、各ソフトウェアスレッドを個別にサンプリングします。したがって、CPU集約foo()、bar()、およびbaz()関数をそれぞれ実行する3つのスレッドがあり、サンプリング周波数が100Hzで、プロファイリングセッションの期間が1秒の場合、それぞれ100サンプルが得られますの関数の。

通常、デシェントプロファイラは、指定されたスレッドでデータをフィルタリングする方法を提供するので、どのホットスポットがどのスレッドに単独で存在しているかを確認することができます。たとえば、主なスレッドが、使用しているフレームワークでUIのレンダリングが行われる場所であれば、主なスレッドで何が起こるかは大きな問題です。バックグラウンドスレッドで実行計算は、アプリケーションの応答性に影響を与える方法を考え出す

は、それ自体で、幅広いトピックであり、多くの場合、アプリケーション固有です。いくつかのパターン:

  • メインスレッドがブロックされる場所を探します。バックグラウンド計算の結果を待つことをブロックしている可能性があります。
  • メインスレッドに、すぐに利用可能なデータがないため何かをスキップしなければならないポイントがあるかどうかを調べます。これは特にUI /レンダリングの処理に共通しています。フレームをレンダリングする必要があるときにデータが準備できていない場合は、フレームをスキップしてUIにユーザーが表示できるようにするコードは何もありません。

これが役に立ちます。

0

マルチスレッドコードをプロファイルする良い方法はありますか?

私はいつも、これらは同じではありませんので、聞いている:
あなたは1を探しているの壁時計の時間を割いているもの)、およびそのアプリケーションをスピードアップするために修正することができ、または2)関数呼び出し数、CPUのセルフタイム、CPUのインクルーシブ時間、ホットパスなど、さまざまな種類の測定?

答えが1であると仮定すると、多くの人と私が使用する方法は、Visual Studio IDEの下で必要に応じて数回だけpause the applicationになります。 これを実行すると、すべてのスレッドが一時停止します。 各スレッドの呼び出しスタックを表示できます。これは、それが何を待っているのか、なぜそれが表示されます。 スレッドのうちの1つ以上が、一時停止の一部で、何らかの計算やシステム待機またはI/Oの処理中で、回避できないと思われるものがあります。

あなたは「貧しい人のプロファイラ」それを呼び出すことができ、 が、ここではそれがプロファイラ出力を超えた方法は次のとおりです。

  • 問題は計算やI/Oである場合は、気にする必要はありません、それがどれであるかを推測し、異なるプロファイリング方法を選択する。いずれにせよ、あなたはそれを見る。

  • 関数/メソッドで費やされる時間の包括的な割合を知りたい場合、おおまかに言えば、関数がスタック上にあるサンプルの割合です。どのコード行でも同じことが言えます。 排他的(自己)分数を知りたい場合は、関数またはコード行が末尾のスタックのにあるときです。

  • 、関数呼び出し関数Bに費やされた時間の何割合を知りたい場合は、仲介を通じて呼び出しB に興味があるなら、それは、AがBに を呼び出すサンプルの一部でありますあなたはそれも見ることができます(コールグラフがあなたに伝えることはできません)。

  • スタックが30レベルの深さで、あるI/Oで終了し、コードのどの部分がそれを引き起こしているのかを知りたい場合は、スタックをスキャンして、君はそれを見つけます。 問題コードに到達する方法は複数ある可能性があるため、これはおそらく「ホットパス」ではないことに注意してください。

  • このようにすると、コードの責任ある行だけでなく、関連するデータ変数の値を調べることができます。 Profilerはこれらの情報を表示できません。あなたは推測する必要があります。

  • ではありませんが多くのことを伝えることで時間を無駄にしません。なぜなら、それらは小さなパーセントをとるためです。の問題です。 (時には、5%以下のような小さなものだけを探していると思うこともありますが、それほど大きなものはありませんが、プロファイラではそのことを仮定することができます。

  • これは、システムコードではなく、コードについて何かできることに集中することができます。

  • 興味のある時間間隔を見つけるためにタイムラインを狩る必要はありません。 あなたはそれを待っているときに一時停止します。それは他の時間にそれを一時停止するのは難しいです。 それはあなたがなぜあなたを待っているのかをあなたに伝えます。