我有一组C ++函数,它们执行一些与图像处理相关的操作。通常我看到最终输出在5-6ms的时间范围内传送。我正在测量使用QueryPerformanceCounter
Win32 API所花费的时间。但是当在具有100个图像的连续循环中运行时,我发现某些图像的性能峰值高达20ms。我的问题是如何分析这些问题。基本上我想确定尖峰是否是由于此代码中的某些延迟引起的,或者是否某些其他任务开始在CPU内运行,因为此操作需要时间。我已经尝试使用GetThreadTimes
API来查看我的线程在CPU内部花费了多少时间但是无法根据这些数字得出结论。解决这些类型问题的标准方法是什么?
答案 0 :(得分:3)
处理过程中突然出现峰值的原因可能是IO,中断,预定进程等等。
考虑到这种低延迟/处理时间操作,这种尖峰很常见。 IMO你可以考虑他们因为上述任何原因(可能会有更多)。最简单的解决方案是使用多次输入进行相同的实验,并将平均值作为最终考虑因素。
要回答有关检查/确认尖峰来源的问题,您可以尝试按照
进行操作使用此设置运行实验并检查行为。
答案 1 :(得分:2)
这是你想要弄清楚的一件令人讨厌的事情,我甚至不会尝试,因为进入具体的妄想是很难的。
一般情况下,应该运行许多迭代的循环(我认为100只看起来太小),然后花费处理图像的平均时间。
这将排除任何可能影响程序性能的意外外部事件。
检查“其他任务是否开始在CPU内部运行”的典型方法是运行程序一次并标记产生该峰值的图像。例如,图像2,4,5和67需要很长时间才能处理。再次运行程序,再次标记哪些图像产生峰值。
如果相同的图像产生这些尖峰,那么它不是由另一个外部任务引起的。
答案 2 :(得分:1)
解决这些类型问题的标准方法是什么?
有实时操作系统(RTOS)可以保证这种延迟。它与Windows或Linux完全不同,是一类操作系统。
但是,即使在通用操作系统上,您仍然可以做一些关于延迟的事情。
一旦你要求你的操作系统读取或写入磁盘的东西 - 无法保证延迟。因此,请避免关键路径上的任何系统功能:
如果您的代码库很大,那么Linux上的strace
或Windows上的Dr Memory
等工具可以跟踪系统调用。
Windows上的多线程是先发制人的。这意味着,有一个系统调度程序,可以随时停止您的线程并在您的CPU上安排另一个线程。和以前一样,有一些RTOS可以避免这种上下文切换,但你可以做些什么:
SetThreadAffinityMask()
(Windows)或sched_setaffinity()
(Linux)的专用CPU - 这有效地提示系统调度程序,以避免在此CPU上调度其他线程; 有perf
(Linux)和Intel VTune
(Windows)等工具可以确认是否存在上下文切换。
更多意外延迟的来源:
希望这有帮助。