2010-11-20 23 views
1

時間単位あたりの繰り返し回数を制限する方法はありますか?たとえば、私はこのようなループを持っています:時間単位あたりの繰り返し回数を制限する

for (int i = 0; i < 100000; i++) 
{ 
    // do stuff 
} 

私はループを上記のように制限したいので、毎秒30回の反復があります。

タイムラインにイテレーションを均等に配置して、最初の0.4秒で30回反復してから0.6秒待つようなことはありません。

これは可能ですか?それは完全に正確である必要はありません(より正確になるとより良いでしょう)。

+0

なぜこれをやりたいですか? – fredoverflow

+0

Nop、あなたはそれをすることはできません。事は、あなたが "タイマー"を探してコードを(1/30)ごとに発火させなければならないということです。 – AraK

+0

@FredOverflow私のプログラムは非常に高速です。それは現在のレートでそれらを処理するのに十分速いではない別のプログラムに無線LAN経由でデータを送信しています。 –

答えて

8

@FredOverflow私のプログラムは、 非常に高速です。 を超えるデータを 現在のレートで処理するには、 ではない別のプログラムに送信しています。 - Richard Knop

次に、送信したデータの最後のチャンクの受信が完了したときに確認応答を送信するプログラムがあるはずです。状況が変わると、他の何かがあなたの欲求不満を引き起こします。

+1

これは正解で、「フロー制御」です。フロー制御にタイマーを使用すると、エラーが発生しやすくなり、データレートに人為的な上限が設定されます。 – Blastfurnace

2

は(GetTickCount()は悪い例であり、それは特定のOSだと悪い精度を持っている)あなたは良いNow()機能を持っていると仮定します。

for (int i = 0; i < 1000; i++){ 
    DWORD have_to_sleep_until = GetTickCount() + EXPECTED_ITERATION_TIME_MS; 
    // do stuff 
    Sleep(max(0, have_to_sleep_until - GetTickCount())); 
}; 
1

あなたがループ内での経過時間を確認することができますが、それはいつもの解決策ではないかもしれ。計算時間はマシンとアルゴリズムの性能に完全に依存するため、開発時間中に最適化します(多くのゲームプログラマは、適切なスムーズなアニメーションのためには少なくとも25〜30フレーム/秒が必要です)。

1

最も簡単な方法(ウィンドウ用)はQueryPerformanceCounter()です。いくつかの疑似コード。

QueryPerformanceFrequency(&freq) 
timeWanted = 1.0/30.0 //time per iteration if 30 iterations/sec 
for i 
    QueryPerf(count1) 
    do stuff 
    queryPerf(count2) 
    timeElapsed = (double)(c2 - c1) * (double)(1e3)/double(freq) //time in milliseconds 
    timeDiff = timeWanted - timeElapsed 
    if (timeDiff > 0) 
     QueryPerf(c3) 
     QueryPerf(c4) 
     while ((double)(c4 - c3) * (double)(1e3)/double(freq) < timeDiff) 
      queryPerf(c4) 
end for 

EDIT:あなたは「やるもの」エリアは、あなたのフレームレートよりも時間がかかる場合や、他のそれは問題ではないことを確認する必要があります。また、ミリ秒の1e3の代わりに、1e9を実行すると、ナノ秒に達することができます(精度がそれほど必要な場合)

警告...これはあなたのCPUを食べるでしょうが、良い「ソフトウェア」タイミングを与えます。あなたが1つ以上のプロセッサを持っている場合にのみ、別のスレッドで実行して、どのguisもロックしないようにしてください。これがマルチスレッドのアプリケーションであれば、ループを停止するためにそこに条件を入れることができます。

+0

正確なタイミングが必要な場合は、この方法を使用します。睡眠機能は劇的に変化し、非常に正確である必要がある場合は非常に良いタイミングを与えることができません。 – g19fanatic

1

@FredOverflow私のプログラムは非常に高速です。それは現在のレートでそれらを処理するのに十分速いではない別のプログラムに無線LAN経由でデータを送信しています。 - リチャードノップ

受信側でバッファやキューが必要な場合があります。クライアントからメッセージを受け取るスレッド(ソケットなど)は、メッセージを取得してキューに入れます。メッセージの実際の消費者はキューから読み取り/ポップします。もちろん、キューの並行処理が必要です。

0

上記のフロー制御方法以外にも、送信者側で正確な特定のデータ送信レートを維持する必要がある場合は、通常、このようにすることができます。

E.x. 10Mbpsで送信する場合は、インターバル1msのタイマーを作成して、1msごとに所定の関数を呼び出します。次に、タイマーハンドラ関数で、2つの静的変数を追跡して追跡します。1)データの送信開始からの経過時間2)最後の呼び出しまでに送信されたデータの量(バイト数)。送信する必要のあるデータの量を簡単に計算できます(または単にスリープして次の呼び出しを待つ)。

このようにすれば、非常に安定した方法でデータの「ストリーミング」を行うことができます。これは通常、ビデオのストリーミングで採用されます。もちろん、タイマーの正確さにも依存します。

関連する問題