有没有办法限制每个时间单位的迭代次数?例如,我有一个这样的循环:
for (int i = 0; i < 100000; i++)
{
// do stuff
}
我想限制上面的循环,因此每秒最多会有30次迭代。
我还希望迭代在时间轴中均匀定位,因此不会在前0.4秒内进行30次迭代,然后等待0.6秒。
这可能吗?它不一定非常精确(虽然越精确越好)。
答案 0 :(得分:8)
@FredOverflow我的程序正在运行 非常快。它正在发送数据 wifi到另一个不是的程序 足够快,可以处理它们 当前利率。 - Richard Knop
然后你应该让你发送数据的程序在收到你发送的最后一块数据然后发送下一个数据块时发送确认。当情况发生变化时,任何其他事情都会让你感到沮丧。
答案 1 :(得分:2)
假设您有一个好的Now()
函数(GetTickCount()
是一个不好的例子,它是特定于操作系统并且精度不佳):
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()));
};
答案 2 :(得分:1)
您可以检查循环内的已用时间,但这可能不是通常的解决方案。由于计算时间完全取决于机器和算法的性能,因此人们在开发期间对其进行优化(例如,许多游戏程序员需要至少25-30帧/秒才能获得适当平滑的动画)。
答案 3 :(得分:1)
最简单的方法(对于Windows)是使用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
编辑:你必须确保'do stuff'区域比你的帧率花费更少的时间,否则无关紧要。如果你做1e9(如果你想要那么高的准确度),你可以一直到纳秒,而不是1e3毫秒,
警告......这会占用您的CPU,但会为您提供良好的'软件'时间......在单独的线程中执行(并且只有当您拥有超过1个处理器时),以便任何guis都不会锁定。如果这是一个多线程的应用程序,你可以在那里放置一个条件来停止循环。
答案 4 :(得分:1)
@FredOverflow我的程序运行得非常快。它通过wifi将数据发送到另一个程序,该程序速度不够快,无法以当前速率处理它们。 - Richard Knop
接收方可能需要缓冲区或队列。从客户端接收消息的线程(如通过套接字)获取消息并将其放入队列中。消息的实际使用者从队列中读取/弹出。当然,您需要对队列进行并发控制。
答案 5 :(得分:0)
除了上面提到的流量控制方法,如果您还需要在发件人部分保持准确的特定数据发送速率。通常可以这样做。
E.x。如果你想以10Mbps发送,创建一个间隔1ms的定时器,这样它每1ms调用一个预定义的函数。然后在计时器处理函数中,通过跟踪2个静态变量1)从发送数据开始经过的时间2)在上次调用之前已经发送了多少字节数据,您可以轻松计算需要发送多少数据在当前通话中(或只是睡觉并等待下一个通话)。
通过这种方式,您可以以非常稳定的方式进行数据“流式传输”,抖动非常小,这通常用于视频流。当然,这也取决于计时器的准确程度。