代码之家  ›  专栏  ›  技术社区  ›  Naveen

分析性能测量中的峰值

  •  4
  • Naveen  · 技术社区  · 7 年前

    我有一组C++函数,用于执行一些与图像处理相关的操作。通常我看到最终输出在5-6ms的时间范围内交付。我正在测量使用 QueryPerformanceCounter Win32 API。但是,当连续循环运行100幅图像时,我看到一些图像的性能峰值高达20ms。我的问题是,我该如何分析这些问题。基本上,我想确定这些尖峰是由于代码中的一些延迟引起的,还是因为这个操作花费了时间而在CPU内开始运行其他任务。我试过使用 GetThreadTimes API来查看我的线程在CPU内花费了多少时间,但我无法根据这些数字得出结论。解决这类问题的标准方法是什么?

    3 回复  |  直到 7 年前
        1
  •  3
  •   Nachiket Kate    7 年前

    处理过程中出现突然峰值的原因可能是IO、中断、计划进程等。

    考虑到如此低的延迟/处理时间操作,这种峰值非常常见。在我看来,你可以考虑他们,因为上述任何原因(可能还有更多)。最简单的解决方案是使用更多输入多次运行同一个实验,并取平均值作为最终考虑。

    要回答您关于检查/确认尖峰来源的问题,您可以尝试以下内容:,

    1. 检查图像中的变化-根据您的评论已排除
    2. 在处理过程中监视资源利用率。检查是否有任何资源阻塞(util是最简单的检查方法,linux上的SAR/NMON实用程序最好,开销最小)
    3. 在系统上保留一些CPU(CPU相关性)用于实验,这些CPU仅用于您的程序,不会在其上运行操作系统任务。任务集是最简单的实用程序。更多详细信息包括 here .

    使用此设置运行实验并检查行为。

        2
  •  2
  •   gsamaras a Data Head    7 年前

    这是一件令人讨厌的事情,你正在试图弄清楚,我甚至不会尝试,因为达成具体的结论是困难的。

    一般来说,应该运行一个循环 许多的 迭代(我认为100次似乎太小了),然后取图像处理的平均时间。

    这将排除任何可能影响程序性能的意外外部事件。


    检查“CPU内是否有其他任务开始运行”的典型方法是运行一次程序,并标记产生该峰值的图像。例如,图像2、4、5和67处理时间过长。再次运行程序几次,并再次标记哪些图像产生尖峰。

    如果相同的图像产生这些尖峰,那么它不是由另一个外部任务引起的。

        3
  •  1
  •   Community CDub    4 年前

    解决这类问题的标准方法是什么?

    实时操作系统(RTO)保证了这些延迟。它与Windows或Linux完全不同。

    但是,即使在通用操作系统上,也可以对延迟采取一些措施。

    1、避免系统调用

    一旦你要求你的操作系统在磁盘上读写一些东西,就不能保证会有任何延迟。因此,避免关键路径上的任何系统功能:

    • 甚至像gettimeofday()这样的函数也可能会导致不可预测的延迟,因此您应该真正避免在时间关键型代码中进行任何系统调用;
    • 使用另一个线程执行IO,并通过共享缓冲区将数据传递给关键代码。

    如果你的代码库很大,那么像 strace 在Linux或 Dr Memory 在Windows上跟踪系统调用。

    2.避免上下文切换

    Windows上的多线程是抢占式的。这意味着,有一个系统调度程序,它可以随时停止你的线程,并在你的CPU上调度另一个线程。如前所述,RTOS允许避免此类上下文切换,但您可以采取一些措施:

    • 确保至少有一个CPU内核用于系统和其他任务;
    • 使用以下命令将每个线程绑定到专用CPU SetThreadAffinityMask() (Windows)或 sched_setaffinity() (Linux)--这有效地提示系统调度器避免在此CPU上调度其他线程;
    • 确保硬件中断转移到另一个CPU;通常中断会转到CPU 0,因此最简单的方法是将线程与CPU 1+绑定;
    • 增加线程优先级,这样调度器就不太可能将您的线程切换到另一个线程。

    有这样的工具 perf (Linux)和 Intel VTune (Windows)以确认存在上下文切换。

    3、避免其他不确定性特征

    几乎没有其他意外延迟的来源:

    • 禁用交换,这样您就可以确定线程内存不会在缓慢且不可预测的磁盘驱动器上交换;
    • 禁用CPU turbo boost——在高性能CPU提升后,总是会出现减速,因此CPU保持其热功率(TDP);
    • 禁用超线程——从调度程序的角度来看,这些是独立的CPU,但实际上每个超线程CPU的性能取决于另一个线程目前正在做什么。

    希望这有帮助。