C++,Timer,毫秒

Prz*_*mak 4 c++ timer

#include <iostream>
#include <conio.h>
#include <ctime>



using namespace std;

double diffclock(clock_t clock1,clock_t clock2)
{
    double diffticks=clock1-clock2;
    double diffms=(diffticks)/(CLOCKS_PER_SEC/1000);
    return diffms;
}
int main()
{
    clock_t start = clock();
    for(int i=0;;i++)
    {

    if(i==10000)break;
    }
    clock_t end = clock();

    cout << diffclock(start,end)<<endl;

    getch();
return 0;
}
Run Code Online (Sandbox Code Playgroud)

所以我的问题来了,它给我一个0,好吧我想要检查我的程序运行多少时间...我在互联网上找到了大量的废话,主要是得到0的相同点因为开始和结束是一样的

这个问题归于C++记忆:<

小智 11

这里有一些问题.首先是你在转到diffclock()功能时显然切换了开始和停止时间.第二个问题是优化.任何启用了优化的合理智能编译器都会抛弃整个循环,因为它没有任何副作用.但即使您解决了上述问题,该程序很可能仍会打印0.如果您试图想象每秒进行数十亿次操作,那么抛出复杂的乱序执行,预测以及现代CPU使用的大量其他技术,甚至CPU也可能优化你的循环.但即使它没有,你需要超过10K的迭代才能使它运行更长时间.你可能需要你的程序运行一两秒才能clock()反映任何内容.

但最重要的问题clock()本身.该功能不适用于任何时间的性能测量.它的作用是为您提供程序使用的处理器时间的近似值.除了可能由任何给定实现使用的近似方法的模糊性质(因为标准不要求任何特定的),POSIX标准也需要CLOCKS_PER_SEC等于1000000独立于实际分辨率.换句话说 - 时钟的精确程度无关紧要,CPU的运行频率无关紧要.简单来说 - 它是一个完全无用的数字,因此是一个完全无用的功能.它仍然存在的唯一原因可能是出于历史原因.所以,请不要使用它.

为了实现您的目标,人们习惯于通过用于读取它的相应CPU指令的名称来读取CPU时间戳,也称为"RDTSC".然而,这些天,这也几乎没用,因为:

  1. 现代操作系统可以轻松地将程序从一个CPU迁移到另一个CPU.你可以想象,在另一个CPU上运行一秒钟之后读取时间戳并没有多大意义.只有在最新的Intel CPU中,计数器才能跨CPU核心同步.总而言之,仍然可以这样做,但必须要特别小心(即一旦可以设置过程的亲和力等).
  2. 测量程序的CPU指令通常无法准确了解实际使用的时间.这是因为在实际程序中可能存在一些系统调用,其中工作由OS内核代表进程执行.在那种情况下,不包括该时间.
  3. OS也可能会暂停执行该过程很长时间.即使只执行了几条指令,对于用户来说它似乎只是一秒钟.因此,这样的性能测量可能是无用的.

那么该怎么办?

在分析时,perf必须使用类似的工具.它可以跟踪许多CPU时钟,缓存未命中,分支,错过的分支,进程从一个CPU移动到另一个CPU的次数,等等.它可以用作工具,也可以嵌入到您的应用程序中(类似于PAPI).

如果问题是关于实际花费的时间,人们会使用挂钟.优选地,高精度的,也不是NTP调整(单调).无论发生了什么,这都显示了经过了多少时间.为此目的clock_gettime()可以使用.它是SUSv2,POSIX.1-2001标准的一部分.鉴于使用你getch()保持终端打开,我假设你正在使用Windows.不幸的是,你没有clock_gettime(),最接近的是性能计数器API:

BOOL QueryPerformanceFrequency(LARGE_INTEGER *lpFrequency);
BOOL QueryPerformanceCounter(LARGE_INTEGER *lpPerformanceCount);
Run Code Online (Sandbox Code Playgroud)

对于便携式解决方案,最好的选择是打开std::chrono::high_resolution_clock().它是在C++ 11中引入的,但得到了大多数工业级编译器(GCC,Clang,MSVC)的支持.

以下是如何使用它的示例.请注意,因为我知道我的CPU将以比毫秒更快的整数方式进行10000次增量,所以我将其更改为微秒.我也宣称计数器volatile希望编译器不会优化它.

#include <ctime>
#include <chrono>
#include <iostream>

int main()
{
    volatile int i = 0; // "volatile" is to ask compiler not to optimize the loop away.
    auto start = std::chrono::steady_clock::now();
    while (i < 10000) {
        ++i;
    }
    auto end = std::chrono::steady_clock::now();
    auto elapsed = std::chrono::duration_cast<std::chrono::microseconds>(end - start);
    std::cout << "It took me " << elapsed.count() << " microseconds." << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

当我编译并运行它时,它会打印:

$ g++ -std=c++11 -Wall -o test ./test.cpp && ./test
It took me 23 microseconds.
Run Code Online (Sandbox Code Playgroud)

希望能帮助到你.祝好运!


小智 5

乍一看,似乎您从较小的值中减去较大的值.你打电话:

diffclock( start, end );
Run Code Online (Sandbox Code Playgroud)

但是,diffclock定义为:

    double diffclock( clock_t clock1, clock_t clock2 ) {

        double diffticks = clock1 - clock2;
        double diffms    = diffticks / ( CLOCKS_PER_SEC / 1000 );

        return diffms;
    }
Run Code Online (Sandbox Code Playgroud)

除此之外,它可能与你转换单位的方式有关.在此页面上使用1000转换为毫秒是不同的:

http://en.cppreference.com/w/cpp/chrono/c/clock