使用StopWatch测量FPS有奇怪的问题

时间:2012-02-01 22:46:14

标签: c# .net multithreading frame-rate

我有一个这样的代码段:

 while(true)
 { 
   myStopWatch.Start();
   DoMyJob();
   myStopWatch.Stop();
   FPS = 1000/myStopWatch.Elapsed.ToMillionSeconds();
   myStopWatch.Reset();
 }

效果很好,我的FPS大约为100(+/- 2)。但有时我只想关注 DoMyJob()性能的某个部分并添加一些反馈,因此我将 DoMyJob()分割为 DoMyJob1() 并添加 DoMyJobs2()。第一部分主要是计算内容,第二部分是对表格上的计算进行可视化,并更新一些指标。

所以代码变成:

 while(true)
 { 
   myStopWatch.Start();
   DoMyJob_1();
   myStopWatch.Stop();
   FPS = 1000/myStopWatch.Elapsed.ToMillionSeconds();
   myStopWatch.Reset();
   DoMyJob_2();
 }

我没想到会因为 DoMyJob1 与原来的 DoMyJob 几乎相同而导致FPS陷入困境。但是哎呀......搞砸了。 FPS变得狂热,以某种方式随机的方式在40到600之间反弹。我消灭了 DoMyJob2(),FPS又回到了稳定的100。

当我深入研究FPS序列时,我发现FPS根本不是随机的 - 它们有4或5个不同的范围,在我的代码中,30-50,100-120,300-360,560- 600等。没有一个数字落入缺口。然后我尝试了另一台笔记本电脑中的代码,问题仍然存在,但只是有不同的范围。我知道StopWatch使用Win32API。是因为它有问题,我在64位系统上运行代码??

BTW:在.NET Windows Form App上测量FPS的最佳方法是什么? (如果FPS = 100或更高)

1 个答案:

答案 0 :(得分:0)

如果DoMyJob_2花费了不同的时间,那么每隔一秒就会有一段时间没有被考虑在内。您可以使用您的方法计算执行DoMyJob_1的平均时间,但不能确定每秒的帧数。例如:

loop 1:
 task 1: 5ms
 reported fps: 1000/5ms = 200
 task 2: 15ms
 real fps: 1000/20ms = 50
loop 2:
 task 1: 5ms
 reported fps: 1000/5ms = 200
 task 2: 25ms
 real fps: 1000/30ms = 33
...

所以我不确定你看到的是什么,但似乎有可能。如果作业的总长度趋于稳定,那么您所描述的内容(波动的报告的fps)实际上可能更有意义,但是您分割作业的方式会使每个部分变化。