Linux 时钟()在 time.h 中的精度
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/8594277/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
clock() precision in time.h
提问by mteffaha
I am trying to calculate the number of ticks a function uses to run and to do so an using the clock()
function like so:
我正在尝试计算函数用于运行的滴答数,并使用如下clock()
函数执行此操作:
unsigned long time = clock();
myfunction();
unsigned long time2 = clock() - time;
printf("time elapsed : %lu",time2);
But the problem is that the value it returns is a multiple of 10000, which I think is the CLOCK_PER_SECOND
. Is there a way or an equivalent function value that is more precise?
但问题是它返回的值是 10000 的倍数,我认为是CLOCK_PER_SECOND
. 有没有更精确的方法或等效的函数值?
I am using Ubuntu 64-bit, but would prefer if the solution can work on other systems like Windows & Mac OS.
我使用的是 64 位 Ubuntu,但希望该解决方案可以在 Windows 和 Mac OS 等其他系统上运行。
采纳答案by Jonathan Leffler
There are a number of more accurate timers in POSIX.
POSIX 中有许多更准确的计时器。
gettimeofday()
- officially obsolescent, but very widely available; microsecond resolution.clock_gettime()
- the replacement forgettimeofday()
(but not necessarily so widely available; on an old version of Solaris, requires-lposix4
to link), with nanosecond resolution.
gettimeofday()
- 正式过时,但非常广泛可用;微秒分辨率。clock_gettime()
- 替换gettimeofday()
(但不一定如此广泛可用;在旧版本的 Solaris 上,需要-lposix4
链接),具有纳秒分辨率。
There are other sub-second timers of greater or lesser antiquity, portability, and resolution, including:
还有其他或多或少具有古老性、便携性和分辨率的亚秒计时器,包括:
ftime()
- millisecond resolution (marked 'legacy' in POSIX 2004; not in POSIX 2008).clock()
- which you already know about. Note that it measures CPU time, not elapsed (wall clock) time.times()
-CLK_TCK
orHZ
. Note that this measures CPU time for parent and child processes.
ftime()
- 毫秒分辨率(在 POSIX 2004 中标记为“legacy”;在 POSIX 2008 中没有)。clock()
- 你已经知道了。请注意,它测量的是 CPU 时间,而不是经过(挂钟)时间。times()
-CLK_TCK
或HZ
。请注意,这会测量父进程和子进程的 CPU 时间。
Do not use ftime()
or times()
unless there is nothing better. The ultimate fallback, but not meeting your immediate requirements, is
不要使用ftime()
或times()
除非没有更好的。最终的回退,但不能满足您的直接要求,是
time()
- one second resolution.
time()
- 一秒分辨率。
The clock()
function reports in units of CLOCKS_PER_SEC
, which is required to be 1,000,000by POSIX, but the increment may happen less frequently (100 times per second was one common frequency). The return value must be defined by CLOCKS_PER_SEC
to get time in seconds.
该clock()
函数以 为单位报告,POSIXCLOCKS_PER_SEC
要求其为1,000,000,但增量发生的频率可能较低(每秒 100 次是一种常见频率)。返回值必须定义为CLOCKS_PER_SEC
以秒为单位获取时间。
回答by janneb
Per the clock() manpage, on POSIX platforms the value of the CLOCKS_PER_SEC macro must be 1000000. As you say that the return value you're getting from clock() is a multiple of 10000, that would imply that the resolution is 10 ms.
根据 clock() 联机帮助页,在 POSIX 平台上,CLOCKS_PER_SEC 宏的值必须为 1000000。正如您所说,从 clock() 获得的返回值是 10000 的倍数,这意味着分辨率为 10 ms .
Also note that clock() on Linux returns an approximation of the processor time used by the program. On Linux, again, scheduler statistics are updated when the scheduler runs, at CONFIG_HZ frequency. So if the periodic timer tick is 100 Hz, you get process CPU time consumption statistics with 10 ms resolution.
另请注意,Linux 上的 clock() 返回程序使用的处理器时间的近似值。同样,在 Linux 上,调度程序统计信息会在调度程序运行时以 CONFIG_HZ 频率更新。因此,如果周期性计时器滴答为 100 Hz,您将获得分辨率为 10 ms 的进程 CPU 时间消耗统计信息。
Walltime measurements are not bound by this, and can be much more accurate. clock_gettime(CLOCK_MONOTONIC, ...) on a modern Linux system provides nanosecond resolution.
Walltime 测量不受此限制,并且可以更准确。现代 Linux 系统上的 clock_gettime(CLOCK_MONOTONIC, ...) 提供纳秒分辨率。
回答by FGH
The most precise (but highly notportable) way to measure time is to count CPU ticks.
测量时间的最精确(但高度不可移植)的方法是计算 CPU 滴答数。
For instance on x86
例如在 x86 上
unsigned long long int asmx86Time ()
{
unsigned long long int realTimeClock = 0;
asm volatile ( "rdtsc\n\t"
"salq , %%rdx\n\t"
"orq %%rdx, %%rax\n\t"
"movq %%rax, %0"
: "=r" ( realTimeClock )
: /* no inputs */
: "%rax", "%rdx" );
return realTimeClock;
}
double cpuFreq ()
{
ifstream file ( "/sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq" );
string sFreq; if ( file ) file >> sFreq;
stringstream ssFreq ( sFreq ); double freq = 0.;
if ( ssFreq ) { ssFreq >> freq; freq *= 1000; } // kHz to Hz
return freq;
}
// Timing
unsigned long long int asmStart = asmx86Time ();
doStuff ();
unsigned long long int asmStop = asmx86Time ();
float asmDuration = ( asmStop - asmStart ) / cpuFreq ();
If you don't have an x86, you'll have to re-write the assembler code accordingly to your CPU. If you needmaximum precision, that's unfortunatelly the only way to go... otherwise use clock_gettime().
如果您没有 x86,则必须根据您的 CPU 重新编写汇编代码。如果您需要最大精度,不幸的是这是唯一的方法……否则使用clock_gettime()。
回答by Scissor
I agree with the solution of Jonathan. Here is the implementation of clock_gettime() with nanoseconds of precision.
我同意乔纳森的解决方案。这是具有纳秒精度的clock_gettime() 的实现。
//Import
#define _XOPEN_SOURCE 500
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
#include <sys/time.h>
int main(int argc, char *argv[])
{
struct timespec ts;
int ret;
while(1)
{
ret = clock_gettime (CLOCK_MONOTONIC, &ts);
if (ret)
{
perror ("clock_gettime");
return;
}
ts.tv_nsec += 20000; //goto sleep for 20000 n
printf("Print before sleep tid%ld %ld\n",ts.tv_sec,ts.tv_nsec );
// printf("going to sleep tid%d\n",turn );
ret = clock_nanosleep (CLOCK_MONOTONIC, TIMER_ABSTIME,&ts, NULL);
}
}
Although It's difficult to achieve ns precision, but this can be used to get precision for less than a microseconds (700-900 ns). printf above is used to just print the thread # (it'll definitely take 2-3 micro seconds to just print a statement).
虽然很难达到 ns 的精度,但这可以用来获得小于一微秒(700-900 ns)的精度。上面的 printf 仅用于打印线程#(打印语句肯定需要 2-3 微秒)。