C# 性能测试的令人困惑的结果
我目前正在开发图像处理应用程序。该应用程序从网络摄像头捕获图像,然后对其进行一些处理。该应用程序需要实时响应(理想情况下处理每个请求的时间小于 50 毫秒)。我一直在对我的代码进行一些计时测试,发现一些非常有趣的东西(见下文)。
clearLog();
log("Log cleared");
camera.QueryFrame();
camera.QueryFrame();
log("Camera buffer cleared");
Sensor s = t.val;
log("Sx: " + S.X + " Sy: " + S.Y);
Image<Bgr, Byte> cameraImage = camera.QueryFrame();
log("Camera output acuired for processing");
每次调用log
时,都会显示自处理开始以来的时间。这是我的日志输出:
[3 ms]Log cleared
[41 ms]Camera buffer cleared
[41 ms]Sx: 589 Sy: 414
[112 ms]Camera output acuired for processing
使用 System.Diagonostics
中的 StopWatch
计算计时。上面显示的时间是累计。所以 Log Clear 花了 3ms。 “相机缓冲区清除”花费了(41-3 = 38ms)。
问题 1
我发现这有点有趣,因为当同一个方法被调用两次时,它会在大约 40 毫秒内执行,而当下次调用它一次时,它会花费更长的时间(大约 70 毫秒)。
分配值实际上不会花那么长时间,对吗?
问题 2
此外,上面记录的每个步骤的时间也会随时间而变化。某些步长的值有时低至 0ms,有时高达 100ms。尽管大多数数字似乎相对一致。
我猜这可能是因为CPU同时被其他进程使用? (如果这是出于其他原因,请告诉我)
是否有某种方法可以确保当该函数运行时,它获得最高优先级?这样速度测试结果就会一直很低(就时间而言)。
编辑
我更改了代码以删除上面的两个空白查询帧,因此代码现在是:
clearLog();
log("Log cleared");
Sensor s = t.val;
log("Sx: " + S.X + " Sy: " + S.Y);
Image<Bgr, Byte> cameraImage = camera.QueryFrame();
log("Camera output acuired for processing");
计时结果现在是:
[2 ms]Log cleared
[3 ms]Sx: 589 Sy: 414
[5 ms]Camera output acuired for processing
接下来的步骤现在需要更长的时间(有时,下一步会跳转到 20 之后) -30ms,而下一步之前几乎是瞬时的)。我猜这是由于CPU调度造成的。有什么办法可以确保 CPU 在运行这段代码时不会被安排做其他事情吗?
I am currently working on an image processing application. The application captures images from a webcam and then does some processing on it. The app needs to be real time responsive (ideally < 50ms to process each request). I have been doing some timing tests on the code I have and I found something very interesting (see below).
clearLog();
log("Log cleared");
camera.QueryFrame();
camera.QueryFrame();
log("Camera buffer cleared");
Sensor s = t.val;
log("Sx: " + S.X + " Sy: " + S.Y);
Image<Bgr, Byte> cameraImage = camera.QueryFrame();
log("Camera output acuired for processing");
Each time the log
is called the time since the beginning of the processing is displayed. Here is my log output:
[3 ms]Log cleared
[41 ms]Camera buffer cleared
[41 ms]Sx: 589 Sy: 414
[112 ms]Camera output acuired for processing
The timings are computed using a StopWatch
from System.Diagonostics
. Timings shown above are cumulative. So Log Clear took 3ms. And "Camera Buffer cleared" took (41-3 = 38ms).
QUESTION 1
I find this slightly interesting, since when the same method is called twice it executes in ~40ms and when it is called once the next time it took longer (~70ms).
Assigning the value can't really be taking that long right?
QUESTION 2
Also the timing for each step recorded above varies from time to time. The values for some steps are sometimes as low as 0ms and sometimes as high as 100ms. Though most of the numbers seem to be relatively consistent.
I guess this may be because the CPU was used by some other process in the mean time? (If this is for some other reason, please let me know)
Is there some way to ensure that when this function runs, it gets the highest priority? So that the speed test results will be consistently low (in terms of time).
EDIT
I change the code to remove the two blank query frames from above, so the code is now:
clearLog();
log("Log cleared");
Sensor s = t.val;
log("Sx: " + S.X + " Sy: " + S.Y);
Image<Bgr, Byte> cameraImage = camera.QueryFrame();
log("Camera output acuired for processing");
The timing results are now:
[2 ms]Log cleared
[3 ms]Sx: 589 Sy: 414
[5 ms]Camera output acuired for processing
The next steps now take longer (sometimes, the next step jumps to after 20-30ms, while the next step was previously almost instantaneous). I am guessing this is due to the CPU scheduling. Is there someway I can ensure the CPU does not get scheduled to do something else while it is running through this code?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
当您要求时,相机可能并没有真正“获取帧”,而是一直在这样做。然后,当您向其请求图像数据且图像数据足够新鲜时,数据会立即返回。但如果您运气不好并且数据已过时,那么您就必须等待更新的图像采集。如果相机的帧率为 25fps,则很可能意味着 50ms 的延迟(不仅是实际的光子收集,还有数据传输)。
尝试将相机设置为较低的分辨率(以便帧速率可以提高),延迟会下降吗?
It might be that the camera does not really "acquire frame" when you ask it to, but does it all the time. Then when you ask it for image data and it is fresh enough, the data returns right away. But if you're unlucky and data is stale, then you get to wait for newer image acquisition. If camera does 25fps it could well mean 50ms delay (not only actual photon collection but the data transfer too).
Try to set the camera into lower resolution (so that framerate could get up), do the delays drop?
如果没有来源,几乎不可能说“什么是可能的”。
计时变得棘手的一件事是秒表是否处于低分辨率模式;编写几个循环只是为了验证您确实可以生成任意测量值(即没有过度粒度的任意毫秒数)可能是值得的。
您尝试过使用分析器吗?这可能会回答您关于该流程当时还在做什么的问题。
Without source, it's almost impossible to say "what's possible".
One thing that would make timing tricky is if stopwatch were in low-resolution mode; it may be worth it to write a few loops just to verify that you can indeed generate arbitrary measurements (i.e. any number of milliseconds without undue granularity).
Have you tried using a profiler? That may answer your question as to what else the process is doing at that time.