我需要在c ++中使用某种方法来跟踪自程序执行以来的毫秒数。我需要精确度以毫秒为单位。 (在我的谷歌搜索中,我发现许多人说包括time.h然后将time()
的输出乘以1000 ......这不起作用。)
答案 0 :(得分:8)
clock
。这有两个问题。首先,它通常没有甚至接近毫秒的分辨率(10-20毫秒可能更常见)。其次,它的一些实现(例如,Unix和类似的)返回CPU时间,而其他(例如,Windows)返回挂起时间。
你还没有真正说过你是想要壁挂时间还是CPU时间,这很难给出一个非常好的答案。在Windows上,您可以使用GetProcessTimes
。这将直接为您提供内核和用户CPU时间。它还会告诉您创建进程的时间,因此如果您想要创建进程后的毫秒数,那么您可以从当前时间(GetSystemTime
)中减去进程创建时间。还提到了QueryPerformanceCounter
。这有一些奇怪之处 - 例如,在某些实现中,它从CPU循环计数器中检索时间,因此当CPU速度发生变化时,其频率会发生变化。其他实现从主板的1.024 MHz定时器读取,其不随CPU速度而变化(并且每个使用的条件并不完全明显)。
在Unix上,您可以使用GetTimeOfDay
来获得相对较高精度的(至少可能性)。如果您想要一个流程的时间,可以使用times
或getrusage
(后者更新,并提供更完整的信息,也可能更精确)。
结论:正如我在评论中所说,没有办法得到你想要的东西。既然你还没有说过你是想要CPU时间还是壁挂时间,即使对于特定的系统,也没有一个正确的答案。你已经“接受”的那个(clock()
)具有在任何系统上可用的优点,但它返回的内容也变化最大。
答案 1 :(得分:1)
请参阅std::clock()
答案 2 :(得分:1)
包含time.h,然后使用clock()函数。它返回自程序启动以来经过的时钟周期数。只需将它除以“CLOCKS_PER_SEC”以获得秒数,然后可以乘以1000以获得毫秒数。
答案 3 :(得分:1)
一些跨平台的解决方案。此代码用于某种基准测试:
#ifdef WIN32
LARGE_INTEGER g_llFrequency = {0};
BOOL g_bQueryResult = QueryPerformanceFrequency(&g_llFrequency);
#endif
//...
long long osQueryPerfomance()
{
#ifdef WIN32
LARGE_INTEGER llPerf = {0};
QueryPerformanceCounter(&llPerf);
return llPerf.QuadPart * 1000ll / ( g_llFrequency.QuadPart / 1000ll);
#else
struct timeval stTimeVal;
gettimeofday(&stTimeVal, NULL);
return stTimeVal.tv_sec * 1000000ll + stTimeVal.tv_usec;
#endif
}
答案 4 :(得分:1)
最便携的方式是使用 clock 功能。它通常会报告程序使用处理器的时间或其近似值。但请注意以下内容:
对于GNU系统,分辨率不是很好。真的很可惜。
在进行分割和分配之前,请注意将所有内容都转换为 double 。
计数器在GNU 32位中保持为32位数,这对于长时间运行的程序来说非常烦人。
在Windows和Linux中,使用“壁挂时间”可以提供更好的分辨率。但正如libc手册所述:如果您正在尝试优化程序或测量其效率,那么了解它使用的处理器时间非常有用。为此,日历时间和已用时间是无用的,因为进程可能花费时间等待I / O或其他进程使用CPU。
答案 5 :(得分:1)
这是一个C ++ 0x解决方案,以及为什么clock()
可能无法按照您的想法执行操作的示例。
#include <chrono>
#include <iostream>
#include <cstdlib>
#include <ctime>
int main()
{
auto start1 = std::chrono::monotonic_clock::now();
auto start2 = std::clock();
sleep(1);
for( int i=0; i<100000000; ++i);
auto end1 = std::chrono::monotonic_clock::now();
auto end2 = std::clock();
auto delta1 = end1-start1;
auto delta2 = end2-start2;
std::cout << "chrono: " << std::chrono::duration_cast<std::chrono::duration<float>>(delta1).count() << std::endl;
std::cout << "clock: " << static_cast<float>(delta2)/CLOCKS_PER_SEC << std::endl;
}
在我的系统上输出:
chrono: 1.36839
clock: 0.36
您会注意到clock()
方法缺少一秒钟。精明的观察者也可能会注意到clock()
看起来分辨率较低。在我的系统上,它以 12毫秒增量,可怕的分辨率滴答作响。
如果您不能或不愿意使用C ++ 0x,请查看Boost.DateTime的ptime microsec_clock::universal_time()
。
答案 6 :(得分:0)
这不是C ++特定的(也不是可移植的),但你可以这样做:
SYSTEMTIME systemDT;
在Windows中。
从那里,您可以访问systemDT struct
的每个成员。
您可以记录程序开始的时间,并将当前时间与记录的时间进行比较(例如systemDT
与systemDTtemp
)。
要刷新,您可以拨打GetLocalTime(&systemDT);
要访问每个成员,您可以执行systemDT.wHour
,systemDT.wMinute
,systemDT.wMilliseconds
。
获取有关SYSTEMTIME的更多信息。
答案 7 :(得分:0)
您想要挂钟时间,CPU时间或其他一些测量吗?这个平台是什么?没有普遍可移植的方法来获得比time()
和clock()
给你更精确的方法,但是......
gettimeofday()
和/或clock_gettime()
,它们提供至少微秒的精度并可以访问各种计时器; 答案 8 :(得分:0)
您可以尝试此代码(从StockFish国际象棋引擎源代码(GPL)获取):
#include <iostream>
#include <stdio>
#if !defined(_WIN32) && !defined(_WIN64) // Linux - Unix
# include <sys/time.h>
typedef timeval sys_time_t;
inline void system_time(sys_time_t* t) {
gettimeofday(t, NULL);
}
inline long long time_to_msec(const sys_time_t& t) {
return t.tv_sec * 1000LL + t.tv_usec / 1000;
}
#else // Windows and MinGW
# include <sys/timeb.h>
typedef _timeb sys_time_t;
inline void system_time(sys_time_t* t) { _ftime(t); }
inline long long time_to_msec(const sys_time_t& t) {
return t.time * 1000LL + t.millitm;
}
#endif
struct Time {
void restart() { system_time(&t); }
uint64_t msec() const { return time_to_msec(t); }
long long elapsed() const {
return long long(current_time().msec() - time_to_msec(t));
}
static Time current_time() { Time t; t.restart(); return t; }
private:
sys_time_t t;
};
int main() {
sys_time_t t;
system_time(&t);
long long currentTimeMs = time_to_msec(t);
std::cout << "currentTimeMs:" << currentTimeMs << std::endl;
Time time = Time::current_time();
for (int i = 0; i < 1000000; i++) {
//Do something
}
long long e = time.elapsed();
std::cout << "time elapsed:" << e << std::endl;
getchar(); // wait for keyboard input
}