2013-03-05 81 views
4
#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++,定时器,毫秒

这个问题转到C++ remeber:<你应该减去最终的

+5

你的优化器会抛出你的for循环,因为它什么都不做?也许在全球范围内增加一项任务。阿洛斯,即使它确实有效,你的开始和结束都会倒退,这样时间会变成负面的。 – 2013-03-05 22:18:21

+1

即使循环未被优化,计数到10000的机会也不会超过1毫秒。现代电脑速度非常快。 – 2013-03-05 22:19:52

+0

你为什么这样做?如果你试图进行基准测试,那么循环可能不是一个好的测试。 – Richard 2013-03-05 22:20:39

回答

4

一眼看来,你似乎正在从较小的值减去较大的值。您致电:

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

+0

Okey队友,它的工作原理是你给的参考,你我试过它copule的时间,它没有,现在我复制了一切...和爆炸,奇迹! 非常感谢。 btw其他人 关于-1的东西......我不知道你在哪里看过它......但如果你听到自己的一瞬间...... -1-1 = 0给你? – Przmak 2013-03-05 22:39:03

+0

@ user2137666 -1 - (-1)== 0对我来说。您? – Slava 2013-03-05 22:47:34

+0

+1。另外,请考虑使用cppreference。 cplus plus dot com是一个充满广告的商业网站。 Cppreference是一个社区驱动程序基于wiki的参考,它是更多更新的当然,并且当然是无广告的。 – 2013-03-05 23:12:14

1

首先 - 启动而不是相反。
文档说如果值不可用clock()返回-1,你检查了吗? 编译你的程序时使用了什么优化级别?如果启用优化,编译器可以完全消除你的循环。

+0

好吧......它不是一个大错误,你甚至可以用减号得到相同的结果,你说得对,它应该被交换:) – Przmak 2013-03-05 22:48:48

3

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

使用优化进行编译确实会删除循环,因此您不得不使用它,或者使循环“执行某些操作”增加循环体​​中循环计数器以外的计数器。至少这就是GCC所做的。

+0

似乎是对的,关于循环短的事情:) – Przmak 2013-03-05 22:47:02

+0

+1发现一个bug :) – 2013-03-05 23:09:45

10

有在这里的几个问题。首先是你明显切换到diffclock()函数时的开始和结束时间。第二个问题是优化。任何启用了优化的合理智能编译器都会将整个循环丢弃,因为它没有任何副作用。但即使你解决了上述问题,程序仍然可以打印0.如果你试图想象每秒钟做数十亿次操作,那么抛出先进的乱序执行,预测和现代CPU所采用的大量其他技术,甚至是CPU优化你的循环。但即使不这样做,为了使其运行时间更长,您也需要10K以上的迭代次数。你可能需要你的程序运行一两秒钟才能得到clock()反映任何东西。

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

为了达到您的要求,人们用来读取CPU Time Stamp也被称为“RDTSC”的对应CPU指令的名称来读取它。然而,这些日子大多也没用,因为:

  1. 现代操作系统可以轻松地将程序从一个CPU迁移到另一个CPU。你可以想象,在另一个CPU上运行一秒钟之后读取时间戳并没有多大意义。只有在最新的英特尔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); 

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

下面是如何使用它的一个例子。请注意,因为我知道我的CPU会以比1毫秒快的整数方式执行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. 

希望它能帮助。祝你好运!