C ++,Timer,毫秒

时间:2013-03-05 22:16:26

标签: 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;
}

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

这个问题归于C ++记忆:&lt;

5 个答案:

答案 0 :(得分:11)

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

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

为了实现您的目标,人们习惯于通过用于读取它的相应CPU指令的名称来读取CPU Time Stamp,也称为“RDTSC”。然而,这些日子,这也是无用的,因为:

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

    在分析时,必须使用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);
    

    对于便携式解决方案,最好的选择是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;
    }
    

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

    $ g++ -std=c++11 -Wall -o test ./test.cpp && ./test
    It took me 23 microseconds.
    

    希望它有所帮助。祝你好运!

答案 1 :(得分:5)

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

diffclock( start, end );

但是,diffclock定义为:

    double diffclock( clock_t clock1, clock_t clock2 ) {

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

        return diffms;
    }

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

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

答案 2 :(得分:3)

问题似乎是循环太短了。我在我的系统上尝试了它,它给了0滴答。我检查了什么是diffticks,它是0.将循环大小增加到100000000,所以有一个明显的时间延迟,我得到-290作为输出(错误 - 我认为差异应该是clock2-clock1所以我们应该得到290而不是-290)。我尝试在分区中将“1000”更改为“1000.0”,但这不起作用。

使用优化进行编译会删除循环,因此您必须不使用它,或使循环“执行某些操作”,例如增加循环体​​中循环计数器以外的计数器。至少那是GCC的作用。

答案 3 :(得分:1)

首先你应该减去结束 - 反之亦然。反之 文档说如果值不可用,clock()返回-1,你检查了吗? 编译程序时使用什么优化级别?如果启用了优化,编译器可以完全消除你的循环。

答案 4 :(得分:0)

注意:这在c ++ 11之后可用。

您可以使用 std :: chrono 库。 std :: chrono有两个不同的对象。 (时间点持续时间)。时间点表示时间点和持续时间,因为我们已经知道术语表示时间间隔或时间跨度。 这个c ++库允许我们减去两个时间点,以获得间隔中经过的时间。因此,您可以设置起点和终点。使用功能,您还可以将它们转换为适当的单位。

使用 high_resolution_clock (该库提供的三个时钟之一)的示例:

#include <chrono> 
using namespace std::chrono;

//在运行功能之前

auto start = high_resolution_clock::now();

//调用函数后

auto stop = high_resolution_clock::now();

减去停止和开始时间点,并使用duration_cast()函数将其转换为所需的单位。预定义的单位是纳秒,微秒,毫秒,秒,分钟和小时。

auto duration = duration_cast<microseconds>(stop - start);
cout << duration.count() << endl;