[英]C/C++ Measuring Program Efficiency
我认为衡量我的程序效率的最好方法是检查它运行的时间,但是当我这样做时,我会不断获得随机时间。
我使用下面的代码所示罗杰·佩特这样的主题:
#include <ctime>
void func()
{
using namespace std;
clock_t begin = clock();
//Function to measure here
clock_t end = clock();
double elapsed_secs = double(end - begin) / CLOCKS_PER_SEC;
}
我认为这是因为我在后台运行了一些程序。
我不想每次都想重新检查我的功能的时间时重新启动计算机,所以我的问题是:有没有更好的方法来衡量程序的效率?
IDE 是 Codeblocks,操作系统是 Win7 64bit。
使用现代的多千兆赫 CPU 和高速 RAM I/O,除非您的代码运行时间超过几分钟,否则测量其执行时间不太可能产生任何有意义的结果。 信噪比太高了。 I/O 中断和自然的抢占式多任务处理会产生太多噪音,并淹没任何有意义的运行时指标。
特别是在您的情况下,在 MS Windows 上,它不断启动各种后台 O/S 进程。 重新启动计算机只会让事情变得更糟。 Windows 操作系统通常会在重新启动后启动无数后台进程,在接下来的几分钟内,这些进程会做某事或其他事情。 通常您需要等待 10-15 分钟,自然背景活动才会平静下来。
您需要测量用户时间。 您可以在基于 UNIX 的系统 ( https://en.wikipedia.org/wiki/Time_(Unix) ) 中使用time
命令来完成此操作。 我不确定微软是否有类似的东西。
用户时间是操作系统为您的进程测量的时间,因此它更准确地描述了您的程序运行了多长时间。 之所以能够做到这一点,是因为它是实体调度任务。
如果您担心 I/O 中断或抢占式多任务处理的噪音,请使用GetThreadTimes函数。
但是,我会更关心clock()
函数的分辨率。 在 Windows 上,我会使用QueryPerformanceCounter函数。
正如其他人已经指出的那样,使用 clock() 是一种不精确的时间测量方式,更好的方法是直接查询 TSC 计数器。 TSC 计数器非常准确,查询速度快,并且能够测量单个指令的执行速度(受一些限制,如下)。
作为如何查询TSC的示例,请参见下面的代码;
#ifdef WIN32
#define uint64_t unsigned __int64
#endif
static inline uint64_t rdtsc (void) {
static struct {
union {
struct { uint32_t hi; uint32_t lo; };
uint64_t ret;
};
} tsc;
asm volatile (
"RDTSCP\n\t"
"mov %%edx, %0\n\t"
"mov %%eax, %1\n\t"
: "=r" (tsc.lo), "=r" (tsc.hi)
:: "%rax", "%rbx", "%rcx", "%rdx"
);
return tsc.ret;
}
// example: uint64_t start = rdtsc();
// // Code goes here
// uint64_t end = rdtsc();
// printf("Code executed in %zd cycles\n", end-start);
使用 TSC 计数器的唯一警告是 TSC 仅在您使用的内核上是准确的,因此对于中断驱动的工作负载或长时间运行的进程,最好查询系统时间计数器。 很久以前,TSC 计数器还受到处理器运行频率的影响。
TLDR; 使用 TSC 测量短代码片段的运行时间。
这是我第一次来这里,所以请善待。
1) 如前所述,对于计时器的“较低”精度(在我们周围),函数 QueryPerformanceCounter() 工作正常。 此外,您应该使用 QueryPerformanceFrequency() 询问此计时器步进的频率。 然后您可以确定从开始到结束的刻度差异并将其除以频率。
2)更高的分辨率(也有提到)是直接读取你机器的TSC(TimeStampCounter)寄存器。 命令 _rdtscp() 是在 Windows 下执行此操作的最佳方法(afaik)。 这里的难点在于确定您的机器当前运行的频率。 一种方法是测量用于睡眠(1000)的滴答声,然后通过简单地将滴答声差异作为频率(以Hz为单位)来确定频率。
1) 的示例代码
#include "Windows.h"
_LARGE_INTEGER Start,Stop,Frequency;
DWORD64 Time_taken;
int YourFunction ()
{
Start = QueryPerformanceCounter();
// Run Code to measure here
Stop = QueryPerformanceCounter();
Frequency = QueryPerformanceFrequency();
Time_taken = (Stop.QuadPart-Start.QuadPart)/Frequency.QuadPart;
}
对于 2)
#include <intrin.h>
#include <stdio.h>
unsigned __int64 Start,Stop,Frequency,Time_taken; // Variables for measurement
unsigned int test; // Pointer-buffer for Machine AUX register (non-relevant)
int YourFunction(void)
{
// Measure current frequency
Start = __rdtscp(&test);
Sleep(1000);
Stop = __rdtscp(&test);
Frequency = Stop-Start;
// Measure your function
Start = __rdtscp(&test);
// Code to measure
Stop = __rdtscp(&test);
Time_taken = (Stop-Start)/Frequency;
}
有关参考,请参阅 1) https://msdn.microsoft.com/de-de/library/windows/desktop/ms644904%28v=vs.85%29.aspx
和 2) https://msdn.microsoft.com/de-de/library/bb385235.aspx
我希望这回答了你的问题。
问候萨沙
在分析器下运行您的代码,可以优化代码但带有调试信息。
对 VerySleepy 有很好的体验: http : //www.codersnotes.com/sleepy/
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.