繁体   English   中英

c ++中的clock()与繁重的CPU负载一致

[英]Is clock() in c++ consistent with heavy CPU loads

现在我基本上有一个程序,它使用时钟来测试我的程序执行某些操作所需的时间,通常它精确到几毫秒。 我的问题是:如果CPU负载很重,我仍会得到相同的结果吗?

时钟只计算在CPU处理我的进程时吗?

让我们假设:多核CPU,但一个不利用多线程的进程

除了同意表明时间取决于许多因素的响应之外,我想提请你注意自C ++ 11以来可用的std::chrono库:

#include <chrono>
#include <iostream>

int main() {
      auto beg = std::chrono::high_resolution_clock::now();
      std::cout << "*** Displaying Some Stuff ***" << std::endl;
      auto end = std::chrono::high_resolution_clock::now();
      auto dur = std::chrono::duration_cast<std::chrono::microseconds>(end - beg);
      std::cout << "Elapsed: " << dur.count() << " microseconds" << std::endl;
    }

按照标准,该程序将使用系统提供的最高精度时钟,并以微秒分辨率打勾(还有其他可用的分辨率; 请参阅文档 )。

样品运行:

$ g++ example.cpp -std=c++14 -Wall -Wextra -O3
$ ./a.out
*** Displaying Some Stuff ***
Elapsed: 29 microseconds

虽然它比依赖C风格的std::clock()更加冗长,但我觉得它能给你更多的表现力,你可以隐藏一个漂亮的界面背后的冗长(例如, 看看我之前的帖子的答案)我在哪里使用std::chrono来构建一个函数计时器)。

clock的功能取决于OS。 在Windows中,从远距离的决定, clock给出了大多数其他操作系统(当然是Linux,MacOS和其他与Unix相关的操作系统)的经过时间。

根据您实际想要实现的目标,可能需要测量经过的时间或CPU时间。

在运行其他进程的系统中,经过时间和CPU使用之间的差异可能很大(当然,如果您的CPU不忙于运行应用程序,例如等待网络数据包通过线路或文件数据从硬盘),然后经过的时间是“avialable”为其他应用程序。

当在同一系统中运行其他进程时,还存在大量错误因素/干扰因素:

  • 如果我们假设您的操作系统支持clock作为CPU时间的度量,那么这里的精度并不总是那么好 - 例如,它可能会根据CPU计时器滴答来计算,并且您的进程可能无法运行“如果它正在进行I / O,则完全打勾。

  • 其他进程可以使用“你的”cpu进行中断处理的部分,在操作系统切换到“将此作为中断时间计算”之前,当通过网络处理数据包或硬盘i / o一段时间之后[通常不是很大,但在一个非常繁忙的系统中,它可能占总时间的百分之几],如果其他进程在“你的”cpu上运行,那么用“你的”进程重新加载缓存的时间到了加载其他进程后的数据,其数据将记入“您的时间”。 这种“干扰”可能会很好地影响您的测量 - 多少取决于系统中“还有什么”。

  • 如果您的进程[通过共享内存]与另一个进程共享数据,那么(在一些情况下,通常是一小部分,但在极端情况下,它可能很重要)会花费一些时间来处理您之间的“缓存 - 窥探请求”进程和其他进程,当您的进程无法执行时。

  • 如果操作系统正在切换任务,那么在您的过程中将花费一半的时间用于切换到您的任务,而在另一个过程中将一半用于切换/切换。 同样,这通常很小,但如果你有一个非常繁忙的系统,有很多过程开关,它可以加起来。

  • 某些处理器类型,例如Intel的HyperThreading也与您的实际核心共享资源,因此只有部分时间在该核心上花费在您的流程中,并且您的流程的缓存内容现在与其他流程的数据和指令共享 - 意味着您的进程可能会被运行在同一CPU核心上的另一个线程从缓存中“逐出”。

  • 同样,多核CPU通常具有共享L3缓存,该缓存会受到CPU其他核心上运行的其他进程的影响。

  • 文件缓存和其他“系统缓存”也会受到其他进程的影响 - 因此,如果您的进程正在读取某些文件,而其他进程也访问文件,则缓存内容将“少于您自己”。如果系统不那么忙。

为了准确测量您的进程使用系统资源的数量,您需要处理器性能计数器(以及可重现的测试用例,因为您可能需要多次运行相同的设置以确保您获得“正确”的性能组合计数器)。 当然,大多数这些计数器都是系统范围的,并且某些类型的处理(例如中断和其他随机干扰)会影响测量,因此如果您没有其他许多(繁忙)进程,那么最准确的结果将是在系统中运行。

当然,在许多情况下,仅测量应用程序的总体时间就足够了。 同样,只要您有一个可重现的测试用例,每次在特定场景中运行时都会给出相同(或至少相似)的时间。

每个应用程序都不同,每个系统都不同。 性能测量是一个巨大的主题,并且很难涵盖所有内容 - 当然,我们不是在这里回答非常具体的问题,“我如何在那里获得我的PI小百万分之一小数是在同一系统中运行的其他进程“或者它可能是什么。

CPU中有共享组件,如最后一级缓存,执行单元(在一个内核中的硬件线程之间),因此在负载很重的情况下,您将获得抖动,因为即使您的应用程序执行了完全相同数量的指令,每条指令也可能需要更多周期(等待内存,因为数据是从缓存,可用执行单元中逐出的),更多周期意味着更多的执行时间(假设Turbo Boost不会补偿)。

如果您寻求精确的仪器,请查看硬件计数器

考虑诸如物理CPU上可用的内核数量,超线程和其他BIOS设置(如Intel CPU上的Turbo Boost)以及在查看CPU密集型任务的时序度量时进行编码时使用的线程技术等因素也很重要。

OpenMP这样的并行化工具提供了用于计算计算和omp_get_wtime( );时间的内置函数,如omp_get_wtime( ); 在使用这种类型的并行化的程序中,它通常比clock()更准确。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM