开发者

Limit iterations per time unit

开发者 https://www.devze.com 2023-01-26 06:12 出处:网络
Is there a way to limit iterations per time unit? For example, I have a loop like this: for (int i = 0; i < 100000; i++)

Is there a way to limit iterations per time unit? For example, I have a loop like this:

for (int i = 0; i < 100000; i++)
{
    // do s开发者_JS百科tuff
}

I want to limit the loop above so there will be maximum of 30 iterations per second.

I would also like the iterations to be evenly positioned in the timeline so not something like 30 iterations in first 0.4s and then wait 0.6s.

Is that possible? It does not have to be completely precise (though the more precise it will be the better).


@FredOverflow My program is running very fast. It is sending data over wifi to another program which is not fast enough to handle them at the current rate. – Richard Knop

Then you should probably have the program you're sending data to send an acknowledgment when it's finished receiving the last chunk of data you sent then send the next chunk. Anything else will just cause you frustrations down the line as circumstances change.


Suppose you have a good Now() function (GetTickCount() is bad example, it's OS specific and has bad precision):

 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()));
};


You can check elapsed time inside the loop, but it may be not an usual solution. Because computation time is totally up to the performance of the machine and algorithm, people optimize it during their development time(ex. many game programmer requires at least 25-30 frames per second for properly smooth animation).


easiest way (for windows) is to use QueryPerformanceCounter(). Some pseudo-code below.

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: You must make sure that the 'do stuff' area takes less time than your framerate or else it doesn't matter. Also instead of 1e3 for milliseconds, you can go all the way to nanoseconds if you do 1e9 (if you want that much accuracy)

WARNING... this will eat your CPU but give you good 'software' timing... Do it in a separate thread (and only if you have more than 1 processor) so that any guis wont lock. You can put a conditional in there to stop the loop if this is a multi-threaded app too.


@FredOverflow My program is running very fast. It is sending data over wifi to another program which is not fast enough to handle them at the current rate. – Richard Knop

What you might need a buffer or queue at the receiver side. The thread that receives the messages from the client (like through a socket) get the message and put it in the queue. The actual consumer of the messages reads/pops from the queue. Of course you need concurrency control for your queue.


Besides the flow control methods mentioned, if you also have the need to maintain an accurate specific data sending rate in your sender part. Usually it can be done like this.

E.x. if you want to send at 10Mbps, create a timer of interval 1ms so it will call a predefined function every 1ms. Then in the timer handler function, by keep tracking of 2 static variables 1)Time elapsed since beginning of sending data 2)How much data in bytes have been sent up to last call, you can easily calculate how much data is needed to be sent in the current call (or just sleep and wait for next call).

By this way, you can do "streaming" of data in a very stable way with very little jitterness, and this is usually adopted in streaming of videos. Of course it also depends on how accurate the timer is.

0

精彩评论

暂无评论...
验证码 换一张
取 消