1

私はいくつかのプロファイリング テストを実行していますが、usleep は便利な機能です。しかし、私のプログラムがスリープしている間、今回はプロファイルに表示されません。

例えば。次のような関数がある場合:

void f1() {
    for (i = 0; i < 1000; i++)
        usleep(1000);
}

プロファイル ツールを gprof として使用すると、f1 はまったく時間を消費しないようです。

私が探しているのは、次のようなアクティブなスリープを行うための空の while ループよりも優れたメソッドです。

while (1) {
    if (gettime()  == whatiwant)
        break;
}
4

7 に答える 7

2

usleep を呼び出すと、CPU が 1 秒間別の作業を行うようになるためです。したがって、現在のスレッドはプロセッサ リソースをまったく使用しません。これは非常に賢い方法です。

アクティブな睡眠はリソースの浪費であるため、絶対に避けるべきものです (最終的には電気を熱に変換することで環境にダメージを与えます;))。

とにかく、本当にそれをしたいのであれば、コンパイラーの最適化によって除外されない、プロセッサーに実際の作業を与える必要があります。例えば

for (i = 0; i < 1000; i++)
    time(NULL);
于 2009-07-14T13:44:21.620 に答える
2

CPU 時間とは対照的に、f1() にかかる合計時間 (壁時計時間、実際の時間、アプリの実行を座って見ている時間) を知りたいと思います。gprof が処理時間の代わりに壁時計時間を提供できるかどうかを調査します。

お使いの OS に依存すると思いますが、usleep がプロファイルでプロセス時間を取っていると見なされない理由は、技術的にはその間何も使用していないためです - 他の実行中のプロセスは (これが * で実行されていると仮定して) nix プラットフォーム)。

于 2009-07-14T13:45:41.727 に答える
2

どのようなシステムを使用していますか? UNIX ライクなシステムでは、 setitimer() を使用して、指定された時間の経過後にプロセスにシグナルを送信できます。これは、探しているタイプの「アクティブ スリープ」を実装するために必要な機能です。

タイマーを設定し、信号を受信するまでループします。

于 2009-07-14T14:19:20.793 に答える
1
for (int i = i; i < SOME_BIG_NUMBER; ++i);

「スリープ」機能の要点は、アプリケーションが実行されていないことです。これはスリープ キューに入れられ、OS は制御を別のプロセスに移します。アプリケーションを実行したいが何もしない場合は、空のループが簡単な解決策です。ただし、スリープのすべての利点が失われます (他のアプリケーションを実行させ、CPU 使用率/電力消費を節約します)。

だからあなたが求めていることは意味がありません。アプリケーションをスリープ状態にすることはできませんが、実行中のままです。

于 2009-07-14T13:45:46.610 に答える
0

私の知る限り、唯一のオプションは while ループを実行することです。オペレーティング システムは、一般に、ユーザーが一定時間待機する場合は、オペレーティング システムに譲ることを想定しています。

マイクロ秒の正確なタイマーを取得できることも潜在的な問題です。私の知る限り、タイミングを行うクロスプラットフォームの方法はありません(クロスプラットフォームのサブマイクロ秒タイマーが欲しいので、誰かがこれについて私を修正してください!:D)。Win32 では、ループ内で十分な時間を費やしてから終了したときに解決するために、いくつかの QueryPerformanceCounter 呼び出しでループを囲むことができます。

例えば

void USleepEatCycles( __int64 uSecs )
{
    __int64 frequency;
    QueryPerformanceFrequency( (LARGE_INTEGER*)&frequency );
    __int64 counter;
    QueryPerformanceCounter( (LARGE_INTEGER*)&counter );

    double dStart = (double)counter / (double)frequency;
    double dEnd   = dStart;
    while( (dEnd - dStart) < uSecs )
    {
        QueryPerformanceCounter( (LARGE_INTEGER*)&counter );
        dEnd = (double)counter / (double)frequency;
    }
}
于 2009-07-14T13:47:03.567 に答える
0

これは gprof で得られる一種の混乱です。関心があるのは壁時計の時間だからです。私はこれを使います

于 2009-07-14T15:11:14.407 に答える