1

C プログラムで選択したループの実行時間を測定して、プログラム (Linux 上) の合計実行時間の何パーセントがこれらのループに費やされているかを確認したいと考えています。パフォーマンスを測定するループを指定できるはずです。ここ数日、いくつかのツール (vtune、hpctoolkit、oprofile) を試しましたが、どれもこれを行うようには見えません。それらはすべて、パフォーマンスのボトルネックを見つけて、それらの時間を表示するだけです。これは、これらのツールがしきい値 (~1ms) を超えた時間のみを保存するためです。したがって、1 つのループの所要時間がそれよりも短い場合、その実行時間は報告されません。

gprof の基本的なブロック カウント機能は、現在サポートされていない古いコンパイラの機能に依存しています。

またはそのようなものを使用して単純なタイマーを手動で作成できますgettimeofdayが、場合によっては正確な結果が得られません。例:

for (i = 0; i < 1000; ++i)
{
    for (j  = 0; j < N; ++j)
    {
        //do some work here
    }
}

ここで、内側のループで費やされた合計時間を測定したいのでgettimeofday、最初のループ内に呼び出しを入れる必要があります。そのgettimeofdayため、それ自体が 1000 回呼び出され、独自のオーバーヘッドが発生し、結果が不正確になります。

4

3 に答える 3

2

CPU の周りにインサーキット エミュレーターまたはブレークアウト ボックスがない限り、単一ループまたは単一命令のタイミングを計ることはできません。CPU や OS などで起こっている他のことによるエラーを減らすために、テスト実行をそれぞれ少なくとも数秒かかるものにまとめて実行する必要があります。

特定のループの実行にかかる時間を正確に知りたい場合、たとえば実行に 1 秒もかからない場合は、反復回数を人為的に増やす必要があります。 「ノイズフロア」より上の数値。次に、その数値を人為的に膨らませた反復回数で割ると、ターゲット ループを 1 回通過するのにかかる時間を表す数値を得ることができます。

さまざまなループ スタイルまたは手法のパフォーマンスを比較したい場合、同じことが当てはまります。測定値を取得するために、テスト コードの反復またはパスの回数を増やす必要があります。あなたが測定しているタイムスライスを支配しています。

これは、CPU によって提供されるサブミリ秒の高性能カウンター、システムの日付時刻クロック、またはテストの経過時間を測定するウォール クロックを使用してパフォーマンスを測定する場合に当てはまります。

それ以外の場合は、ホワイト ノイズを測定しているだけです。

于 2010-04-29T19:06:08.670 に答える
0

簡単に取得できるので、パーセンテージを探しているとうれしいです。実行するだけです。実行速度が速い場合は、外側のループを配置して、かなり長い時間がかかるようにします。それはパーセンテージに影響しません。実行中にスタックショットを取得します。gdbで Ctrl-Break を使用するか、 pstackまたはlsstackを使用してこれを行うことができます。気になるコードが表示されているスタックショットの割合を確認してください。

ループに 0.2 (20%) などの時間の一部がかかり、N=20 のサンプルを取得するとします。次に、それらを表示する必要があるサンプル数は平均 20 * 0.2 = 4 になり、サンプル数の標準偏差は sqrt(20 * 0.2 * 0.8) = sqrt(3.2) = 1.8 になるため、より精度が必要な場合、より多くのサンプルを取得します。(個人的には、精度は過大評価されていると思います。)

于 2010-04-30T14:44:01.517 に答える
0

通常、内側のループで費やされた時間を測定したい場合は、時間取得ルーチンを外側のループの外に置き、(外側の) ループ数で割ります。内側のループの時間が比較的一定であると予想される場合j、つまり.

プロファイリング命令には独自のオーバーヘッドが発生しますが、おそらくオーバーヘッドはどこに挿入されても同じであるため、「すべてが洗い流されます」。おそらく、比較された 2 つのプロセスの実行時間にかなりの違いがあり、このような関数呼び出しのペアが問題にならないスポットを探していると思われます (時間を取得するために「最後」にも 1 つ必要なので)。デルタ) 1 つのルーチンが他のルーチンの 2 倍以上のコストがかかるためです。

ほとんどのプラットフォームは、ある種のより高い解像度のタイマーも提供しますが、ここで使用するものは API の背後に隠されているため、「クライアント」コードはクロスプラットフォームです。ちょっと見ただけで確実に上達します。ここでも、1 ミリ秒を超える精度が得られる可能性はほとんどないため、コードを連続して数回実行し、実行全体の時間を計測することをお勧めします (次に、ループ カウントで割ります)。

于 2010-04-29T18:51:44.337 に答える