繁体   English   中英

C/C++ 测量程序效率

[英]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.

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