#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;
答案 0 :(得分:11)
这里有一些问题。第一个是你在转到diffclock()
函数时显然切换了开始和停止时间。第二个问题是优化。任何启用了优化的合理智能编译器都会抛弃整个循环,因为它没有任何副作用。但即使您解决了上述问题,该程序很可能仍会打印0.如果您试图想象每秒进行数十亿次操作,那么抛出复杂的乱序执行,预测以及现代CPU使用的大量其他技术,甚至CPU也可能优化你的循环。但即使它没有,你需要超过10K的迭代才能使它运行更长时间。你可能需要你的程序运行一两秒才能让clock()
反映任何内容。
但最重要的问题是clock()
本身。该功能不适用于任何时间的性能测量。它的作用是为您提供程序使用的近似处理器时间。除了可能由任何给定实现使用的近似方法的模糊性质(因为标准不要求任何特定的),POSIX标准还要求CLOCKS_PER_SEC
等于1000000
,而不是实际分辨率。换句话说 - 时钟的精确程度无关紧要,CPU的运行频率无关紧要。简单来说 - 它是一个完全无用的数字,因此是一个完全无用的功能。它仍然存在的唯一原因可能是出于历史原因。所以,请不要使用它。
为了实现您的目标,人们习惯于通过用于读取它的相应CPU指令的名称来读取CPU Time Stamp,也称为“RDTSC”。然而,这些日子,这也是无用的,因为:
那该怎么办?
在分析时,必须使用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转换为毫秒是不同的:
答案 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;