现在我基本上有一个程序,它使用时钟来测试我的程序执行某些操作所需的时间,通常它精确到几毫秒。我的问题是:如果CPU负载很重,我仍会得到相同的结果吗?
只有当CPU处理我的进程时才计时?
让我们假设:多核CPU但是没有利用多线程的进程
答案 0 :(得分:3)
除了同意表明时间取决于许多因素的回复之外,我想提请您注意自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;
}
根据标准,该程序将使用系统提供的最高精度时钟,并以微秒分辨率打勾(还有其他可用的分辨率; see the docs)。
示例运行:
$ g++ example.cpp -std=c++14 -Wall -Wextra -O3
$ ./a.out
*** Displaying Some Stuff ***
Elapsed: 29 microseconds
虽然它比依赖C风格的std::clock()
更加冗长,但我觉得它会给你更多的表现力,你可以隐藏一个漂亮的界面背后的冗长(例如,see my answer to a previous post我使用std::chrono
来构建函数计时器。
答案 1 :(得分:3)
clock
的功能取决于操作系统。在Windows中,从远距离的决定中,clock
给出了大多数其他操作系统(当然是Linux,MacOS和其他与Unix相关的操作系统)的经过时间。
根据您实际想要实现的目标,经过时间或CPU时间可能是您想要测量的。
在运行其他进程的系统中,经过时间和CPU使用率之间的差异可能很大(当然,如果您的CPU不忙于运行您的应用程序,例如,等待网络数据包继续运行或来自硬盘的文件数据),其他应用程序的经过时间是“可用的”。
当同一系统中正在运行其他进程时,还存在大量错误因素/干扰因素:
如果我们假设您的操作系统支持clock
作为CPU时间的度量,那么这里的精度并不总是那么好 - 例如,它可能会根据CPU计时器滴答来计算如果它正在进行I / O操作,那么您的流程可能无法运行“完整刻度”。
在通过网络处理数据包或硬盘i / o操作系统切换到“将此作为中断时间”时,其他进程可能会使用“你的”cpu来处理中断处理的部分内容在某个百分比的时间[通常不是很大的数量,但在一个非常繁忙的系统中,它可能是总时间的百分之几],如果其他进程在“你的”CPU上运行,则重新加载缓存的时间加载其他进程后,“你的”进程数据会将数据计入“你的时间”。这种“干扰”可能会很好地影响您的测量 - 多少取决于系统中“还有什么”。
如果您的进程[通过共享内存]与另一个进程共享数据,那么也会(再次,通常是一小部分,但在极端情况下,它可能很重要)花费一些时间来处理“缓存”当您的进程无法执行时,-snoop请求“在您的进程和其他进程之间”。
如果操作系统正在切换任务,那么在您的过程中将花费一半的时间用于切换到/从您的任务切换,而另一个过程中的一半将被切入/切出。同样,这通常很小,但如果你有一个非常繁忙的系统,有很多过程开关,它可以加起来。
某些处理器类型,例如英特尔的HyperThreading还与您的实际核心共享资源,因此只有部分时间在该核心上花费在您的流程中,并且您的流程的缓存内容现在与其他流程的数据和指令共享 - 这意味着您的流程可能会得到通过在同一CPU核上运行的另一个线程从缓存中“逐出”。
同样,多核CPU通常具有共享的L3缓存 受到在CPU其他核心上运行的其他进程的影响。
文件缓存和其他“系统缓存”也会受到其他进程的影响 - 因此,如果您的进程正在读取某些文件,而其他进程也访问文件,则缓存内容将会如果系统不那么忙,那就“少了你”。
为了准确测量您的进程使用系统资源的数量,您需要处理器性能计数器(以及可重现的测试用例,因为您可能需要多次运行相同的设置以确保获得“正确”性能计数器的组合)。当然,大多数这些计数器都是系统范围的,并且某些类型的处理(例如中断和其他随机干扰)会影响测量,因此如果您没有其他许多(繁忙)进程,那么最准确的结果将是在系统中运行。
当然,在许多情况下,仅测量应用程序的总体时间就足够了。同样,只要您有一个可重现的测试用例,每次在特定场景中运行时都会给出相同(或至少相似)的时间。
每个应用程序都不同,每个系统都不同。性能测量是一个巨大的主题,并且很难涵盖所有内容 - 当然,我们不是在这里回答非常具体的问题,“我如何在那里获得我的PI小百万分之一小数是在同一系统中运行的其他进程“或者它可能是什么。”
答案 2 :(得分:1)
CPU中有共享组件,如最后一级缓存,执行单元(一个核心内的硬件线程之间),因此在负载很重的情况下会产生抖动,因为即使您的应用程序执行了完全相同数量的指令,每条指令也可能需要更多周期(等待内存,因为数据是从缓存,可用执行单元中逐出的),更多周期意味着更多的执行时间(假设Turbo Boost不会补偿)。
如果您寻求精确的乐器,请查看hardware counters。
考虑物理CPU上可用内核数量,超线程和其他BIOS设置(如Intel CPU上的Turbo Boost)以及在查看CPU密集型任务的时序指标时进行编码时使用的线程技术等因素也很重要。
像OpenMP这样的并行化工具提供了用于计算计算和挂起时间的内置函数,如omp_get_wtime( );
,这些函数在使用此类并行化的程序中通常比clock()
更准确