用C++代码计算时间

6

我知道这个问题在stackoverflow上已经被问了很多次,但没有一个真正帮助到我,所以我又来问一遍。

我正在使用Windows XP,并运行Visual Studio C++ 2008。

我需要的所有代码都是使用time.h编写的,但我认为它在这里可能不起作用,因为结果让我感到怀疑。

所以这就是我想要的。

star time = get time some how (this is my question)

my code

end time = get time some how (this is my question)

time passed = start time - end time

你有什么“怀疑”的地方? - anon
1
你的代码执行速度太快了,time.h库无法捕捉到它的精度 - 使用提供更高精度的解决方案(请参见我的答案)。 - Kornel Kisielewicz
7个回答

8

以下是我用来打印毫秒时间的代码。

void StartTimer( _int64 *pt1 )
{
   QueryPerformanceCounter( (LARGE_INTEGER*)pt1 );
}

double StopTimer( _int64 t1 )
{
   _int64 t2, ldFreq;

   QueryPerformanceCounter( (LARGE_INTEGER*)&t2 );
   QueryPerformanceFrequency( (LARGE_INTEGER*)&ldFreq );
   return ((double)( t2 - t1 ) / (double)ldFreq) * 1000.0;
}

使用方法如下:

    _int64 t1;

    StartTimer( &t1 );

    // do some stuff

    printf( "Time = %.3f\n", StopTimer( t1 ));

4
你需要一个高精度计时器。如果使用Visual Studio,请使用QueryPerformanceCounter
如果精度仍然不够,可以使用编译器内置函数:
#include <intrin.h>
#pragma intrinsic(__rdtsc)

unsigned __int64 ticks = __rdtsc();

在这里查看关于该内在链接的信息。

两种解决方案仅适用于Windows,后者可能仅适用于MSVC。如果需要,我可以发布一个类似的解决方案,适用于GCC / Linux。


我该如何将它转换为毫秒? - itsaboutcode
@itsaboutcode,不幸的是,由于这些低级性能函数的存在,没有确定的方法可以将其转换为毫秒,因为结果取决于您的处理器速度。您可以使用Sleep事先计算出一个ticks/second值,然后进行转换。 - Kornel Kisielewicz
2
在多核或多插槽系统上使用RDTSC时要小心!系统中的每个CPU核心都有一个单独的时间戳计数器,它们可能同步,也可能不同步。通常需要一个驱动程序定期同步跨核心的时间戳计数器。除非您明确设置了进程的线程亲和性,否则操作系统可以自由地将其从一个核心移动到另一个核心。如果核心的TSC不同步,则可以从不同的计数器获取起始和停止时间,并且差异可能会大大错误--甚至为负! - Die in Sente
2
使用RDTSC的另一个问题是,您必须确切地知道CPU核心频率才能将其转换为秒。 但CPU核心时钟并不是恒定的! 它正在通过电源管理调高或降低。 - Die in Sente

1

通常人们会这样做来测量一些小的时间间隔:

t0 = getTime();

for(int i = 0; i<1000000; ++i) {
  your code
}

t1 = getTime();

timePassed = (t1-t0)/1000000;

1

如果你使用的是Windows系统,GetTickCount()函数是一个非常方便的方法来获取高于1秒的计时器。 GetTickCount的分辨率取决于您的操作系统,但它可能在10毫秒到16毫秒之间。

请注意,对于快速操作,仅执行一次代码是不够的。您的代码可能只运行了0.02毫秒,这意味着您将从诸如GetTickCount的计数器中获得0。您的代码可能没有足够长的时间来使计时器“滴答”到下一个值。解决方案是在循环中运行您的代码一百万次或其他次数,计时整个过程,然后除以一百万。


我正在使用这个函数,但没有结果。 - itsaboutcode
@itsaboutcode:在捕获“开始”和“结束”时间之间,您运行代码的次数有多少次? - Greg Hewgill
只需要一次,那有什么关系,它的代码非常长...大约有6个函数和总共250行代码。 - itsaboutcode
@itsaboutcode:请阅读我的回答的第二段。仅运行您的代码一次是不够的。 - Greg Hewgill

0

Kornel的建议使用QueryPerformanceCounter是一个非常好的建议。

如果这对你不起作用,而且你不介意另一个仅适用于Windows的解决方案,请使用Windows的“多媒体定时器”。在Visual Studio帮助文件中搜索“timeBeginPeriod”,“timeEndPeriod”和“Using Multimedia Timers”。

要使用多媒体定时器,您需要包含头文件并链接winmm.lib:

#include <mmsystem.h>
#pragma comment( lib, "winmm" )     //  need this library for multimedia timers

0

这个正常工作

#include <windows.h>

SYSTEMTIME startTime;
GetSystemTime(&startTime);
WORD startmillis = (startTime.wSecond * 1000) + startTime.wMilliseconds;

// Do some stuff

SYSTEMTIME endTime;
GetSystemTime(&endTime);
WORD endmillis = (endTime.wSecond * 1000) + endTime.wMilliseconds;

WORD millis = startmillis - endmillis ;

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接