C中的最佳时序方法?
计算高分辨率和可移植性的代码段的最佳方式是什么?
/* Time from here */ ProcessIntenseFunction(); /* to here. */ printf("Time taken %d seconds %d milliseconds", sec, msec);
有没有一个标准的库可以有一个跨平台的解决scheme?
我认为这应该工作:
#include <time.h> clock_t start = clock(), diff; ProcessIntenseFunction(); diff = clock() - start; int msec = diff * 1000 / CLOCKS_PER_SEC; printf("Time taken %d seconds %d milliseconds", msec/1000, msec%1000);
gettimeofday()可能会做你想要的。
如果您使用的是英特尔硬件,请阅读如何读取CPU实时指令计数器。 它会告诉你处理器启动后执行的CPU周期数。 这可能是性能测量可以获得的最好的最低开销计数器。
请注意,这是CPU周期数。 在Linux上,你可以从/ proc / cpuinfo获得CPU速度,并分割得到秒数。 把它转换成double是非常方便的。
当我在我的箱子上运行这个,我得到了
11867927879484732 11867927879692217 花了这么长时间才打电话给printf:207485
这是英特尔开发人员指南 ,提供了大量的细节。
#include <stdio.h> #include <stdint.h> inline uint64_t rdtsc() { uint32_t lo, hi; __asm__ __volatile__ ( "xorl %%eax, %%eax\n" "cpuid\n" "rdtsc\n" : "=a" (lo), "=d" (hi) : : "%ebx", "%ecx"); return (uint64_t)hi << 32 | lo; } main() { unsigned long long x; unsigned long long y; x = rdtsc(); printf("%lld\n",x); y = rdtsc(); printf("%lld\n",y); printf("it took this long to call printf: %lld\n",yx); }
gettimeofday将在系统时钟的分辨率内精确到微秒的时间。 您也可能想要查看SourceForge上的High Res Timers项目。
我使用SDL库中的 SDL_GetTicks 。
高分辨率是相对的…我正在看的例子,他们大多数毫秒。 但对我来说,测量微秒是很重要的。 我还没有看到一个平台独立的解决scheme微秒,并认为像下面的代码将是有用的。 我只是暂时在windows上进行计时,在AIX / Linux上执行相同操作时,很可能会添加gettimeofday()实现。
#ifdef WIN32 #ifndef PERFTIME #include <windows.h> #include <winbase.h> #define PERFTIME_INIT unsigned __int64 freq; QueryPerformanceFrequency((LARGE_INTEGER*)&freq); double timerFrequency = (1.0/freq); unsigned __int64 startTime; unsigned __int64 endTime; double timeDifferenceInMilliseconds; #define PERFTIME_START QueryPerformanceCounter((LARGE_INTEGER *)&startTime); #define PERFTIME_END QueryPerformanceCounter((LARGE_INTEGER *)&endTime); timeDifferenceInMilliseconds = ((endTime-startTime) * timerFrequency); printf("Timing %fms\n",timeDifferenceInMilliseconds); #define PERFTIME(funct) {unsigned __int64 freq; QueryPerformanceFrequency((LARGE_INTEGER*)&freq); double timerFrequency = (1.0/freq); unsigned __int64 startTime; QueryPerformanceCounter((LARGE_INTEGER *)&startTime); unsigned __int64 endTime; funct; QueryPerformanceCounter((LARGE_INTEGER *)&endTime); double timeDifferenceInMilliseconds = ((endTime-startTime) * timerFrequency); printf("Timing %fms\n",timeDifferenceInMilliseconds);} #endif #else //AIX/Linux gettimeofday() implementation here #endif
用法:
PERFTIME(ProcessIntenseFunction()); or PERFTIME_INIT PERFTIME_START ProcessIntenseFunction() PERFTIME_END
如果你不想CPU时间,那么我认为你正在寻找的是timeval结构。
我使用下面的来计算执行时间:
int timeval_subtract(struct timeval *result, struct timeval end, struct timeval start) { if (start.tv_usec < end.tv_usec) { int nsec = (end.tv_usec - start.tv_usec) / 1000000 + 1; end.tv_usec -= 1000000 * nsec; end.tv_sec += nsec; } if (start.tv_usec - end.tv_usec > 1000000) { int nsec = (end.tv_usec - start.tv_usec) / 1000000; end.tv_usec += 1000000 * nsec; end.tv_sec -= nsec; } result->tv_sec = end.tv_sec - start.tv_sec; result->tv_usec = end.tv_usec - start.tv_usec; return end.tv_sec < start.tv_sec; } void set_exec_time(int end) { static struct timeval time_start; struct timeval time_end; struct timeval time_diff; if (end) { gettimeofday(&time_end, NULL); if (timeval_subtract(&time_diff, time_end, time_start) == 0) { if (end == 1) printf("\nexec time: %1.2fs\n", time_diff.tv_sec + (time_diff.tv_usec / 1000000.0f)); else if (end == 2) printf("%1.2fs", time_diff.tv_sec + (time_diff.tv_usec / 1000000.0f)); } return; } gettimeofday(&time_start, NULL); } void start_exec_timer() { set_exec_time(0); } void print_exec_timer() { set_exec_time(1); }