如何用C来度量时间间隔?

如何用C来度量时间间隔?,c,timer,C,Timer,我想用C来测量时间,我很难弄清楚,我想要的是这样的东西: long start_time, end_time, elapsed; start_time = clock(); // Do something end_time = clock(); elapsed = (end_time - start_time) / CLOCKS_PER_SEC * 1000; void your_timer_cb (struct ticktimer *t) { /* do your stuff her

我想用C来测量时间,我很难弄清楚,我想要的是这样的东西:

long start_time, end_time, elapsed;

start_time = clock();
// Do something
end_time = clock();

elapsed = (end_time - start_time) / CLOCKS_PER_SEC * 1000;
void your_timer_cb (struct ticktimer *t) {
  /* do your stuff here */
}
  • 启动计时器
  • 运行一个方法
  • 停止计时
  • 报告所用时间(至少达到微精度)
任何帮助都将不胜感激


(我使用mingw在windows中编译)

提供1微秒分辨率的高分辨率计时器是特定于系统的,因此您必须在不同的操作系统平台上使用不同的方法来实现这一点。您可能感兴趣的是检查下面的文章,它基于下面描述的函数实现跨平台C++计时器类:

  • [宋浩安-高解析度定时器][1]

窗口

Windows API提供了极高分辨率的计时器函数:
QueryPerformanceCounter()
,返回当前经过的节拍;以及
QueryPerformanceFrequency()
,返回每秒节拍数

例如:

#include <stdio.h>
#include <windows.h>                // for Windows APIs

int main(void)
{
    LARGE_INTEGER frequency;        // ticks per second
    LARGE_INTEGER t1, t2;           // ticks
    double elapsedTime;

    // get ticks per second
    QueryPerformanceFrequency(&frequency);

    // start timer
    QueryPerformanceCounter(&t1);

    // do something
    // ...

    // stop timer
    QueryPerformanceCounter(&t2);

    // compute and print the elapsed time in millisec
    elapsedTime = (t2.QuadPart - t1.QuadPart) * 1000.0 / frequency.QuadPart;
    printf("%f ms.\n", elapsedTime);
}
#include <stdio.h>
#include <sys/time.h>                // for gettimeofday()

int main(void)
{
    struct timeval t1, t2;
    double elapsedTime;

    // start timer
    gettimeofday(&t1, NULL);

    // do something
    // ...

    // stop timer
    gettimeofday(&t2, NULL);

    // compute and print the elapsed time in millisec
    elapsedTime = (t2.tv_sec - t1.tv_sec) * 1000.0;      // sec to ms
    elapsedTime += (t2.tv_usec - t1.tv_usec) / 1000.0;   // us to ms
    printf("%f ms.\n", elapsedTime);
}

使用time.h库,尝试以下操作:

long start_time, end_time, elapsed;

start_time = clock();
// Do something
end_time = clock();

elapsed = (end_time - start_time) / CLOCKS_PER_SEC * 1000;
void your_timer_cb (struct ticktimer *t) {
  /* do your stuff here */
}

下面是我编写的头文件,用于进行一些简单的性能分析(使用手动计时器):

\ifndef\uuuzentimer\uh__
#定义__
#ifdef启用\u ZENTIMER
#包括
#ifdef WIN32
#包括
#否则
#包括
#恩迪夫
#如果你有能力
#包括
#elif有两种类型
#包括
#否则
typedef无符号字符uint8;
typedef无符号长整数uint32\u t;
typedef无符号长uint64\u t;
#恩迪夫
#ifdef_uucplusplus
外部“C”{
#布拉格}
#endif/*\uuu cplusplus*/
#每100万秒定义ZTIME\u USEC\u
/*ztime_t代表usec*/
typedef uint64\u t ztime\t;
#ifdef WIN32
静态uint64定时器频率=0;
#恩迪夫
静态空隙
ztime(ztime_t*ztimep)
{
#ifdef WIN32
QueryPerformanceCounter((大整数*)ztimep);
#否则
结构时间值电视;
gettimeofday(&tv,NULL);
*ztimep=((uint64_t)tv.tv_sec*ZTIME_USEC_PER_sec)+tv.tv_USEC;
#恩迪夫
}
枚举{
ZTIMER_非活动=0,
ZTIMER_激活=(1次启动);
}
静态空隙
ZenTimerStop(ztimer\u t*ztimer)
{
ztimer=ztimer?ztimer:&uuuuztimer;
ztime(&ztimer->stop);
ztimer->state=ztimer\u未激活;
}
静态空隙
ZenTimerPause(ztimer\u t*ztimer)
{
ztimer=ztimer?ztimer:&uuuuztimer;
ztime(&ztimer->stop);
ztimer->state |=ztimer|u暂停;
}
静态空隙
ZentimerSume(ztimer\u t*ztimer)
{
现在开始,三角洲;
ztimer=ztimer?ztimer:&uuuuztimer;
/*取消暂停*/
ztimer->state&=~ztimer\u暂停;
ztime(现在和现在);
/*计算暂停后的时间*/
增量=现在-时间->停止;
/*调整开始时间以考虑暂停后经过的时间*/
ztimer->start+=增量;
}
双稳态
Zentimer复发(ztimer_t*ztimer,uint64_t*usec)
{
#ifdef WIN32
静态uint64_t freq=0;
ztime_t delta,停止;
如果(频率==0)
QueryPerformanceFrequency((大整数*)&freq);
#否则
#定义每秒的频率ZTIME\u USEC\u
ztime_t delta,停止;
#恩迪夫
ztimer=ztimer?ztimer:&uuuuztimer;
如果(ztimer->state!=ztimer\u活动)
stop=ztimer->stop;
其他的
ztime(&stop);
增量=停止-ztimer->启动;
如果(usec!=NULL)
*usec=(uint64_t)(增量*((双)ZTIME_usec_/秒/(双)频率));
返回(双)增量/(双)频率;
}
静态空隙
ZenTimerReport(ztimer\u t*ztimer,const char*oper)
{
fprintf(stderr,“ZenTimer:%s占用%.6f秒\n”,oper,ZentimerRecursed(ztimer,NULL));
}
#ifdef_uucplusplus
}
#endif/*\uuu cplusplus*/
#否则/*!启用定时器*/
#定义ZenTimerStart(ztimerp)
#定义ZenTimerStop(ztimerp)
#定义ZenTimerPause(ztimerp)
#定义ZentimerSume(ztimerp)
#定义ZentimeRecursed(ztimerp,usec)
#定义ZenTimerReport(ztimerp,oper)
#endif/*启用定时器*/
#endif/*\uuu ZENTIMER\uh\uu*/
ztime()
函数是您需要的主要逻辑-它获取当前时间并将其存储在以微秒为单位的64位uint中。然后,您可以稍后进行简单的数学运算,以找出经过的时间

ZenTimer*()
函数只是一个助手函数,用于获取指向简单计时器结构的指针,
ztimer\u t
,该结构记录开始时间和结束时间。
ZenTimerPause()
/
ZenTimerSume()
函数允许您暂停并恢复计时器,以防打印出一些不需要计时的调试信息


如果您的Linux系统支持,clock_gettime(clock_单调)应该是一个不受系统日期更改(例如NTP守护进程)影响的高分辨率计时器。

在Linux上,您可以使用:


下面是一组通用的C函数,用于基于gettimeofday()系统调用的计时器管理。所有计时器属性都包含在一个ticktimer结构中—所需的时间间隔、自计时器初始化以来的总运行时间、指向所需回调的指针、调用回调的次数。回调函数如下所示:

long start_time, end_time, elapsed;

start_time = clock();
// Do something
end_time = clock();

elapsed = (end_time - start_time) / CLOCKS_PER_SEC * 1000;
void your_timer_cb (struct ticktimer *t) {
  /* do your stuff here */
}
要初始化和启动计时器,请调用ticktimer\u init(计时器、间隔、ticktimer\u RUN、计时器\u cb,0)

在程序的主循环中调用ticktimer_tick(您的计时器),它将决定调用回调是否经过了适当的时间

要停止计时器,只需调用ticktimer\u ctl(您的计时器,ticktimer\u stop)

ticktimer.h:

#ifndef __TICKTIMER_H
#define __TICKTIMER_H

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/time.h>
#include <sys/types.h>

#define TICKTIMER_STOP         0x00
#define TICKTIMER_UNCOMPENSATE 0x00
#define TICKTIMER_RUN          0x01
#define TICKTIMER_COMPENSATE   0x02

struct ticktimer {
  u_int64_t tm_tick_interval;
  u_int64_t tm_last_ticked;
  u_int64_t tm_total;
  unsigned ticks_total;
  void (*tick)(struct ticktimer *);
  unsigned char flags;
  int id;
};

void ticktimer_init (struct ticktimer *, u_int64_t, unsigned char, void (*)(struct ticktimer *), int);
unsigned ticktimer_tick (struct ticktimer *);
void ticktimer_ctl (struct ticktimer *, unsigned char);
struct ticktimer *ticktimer_alloc (void);
void ticktimer_free (struct ticktimer *);
void ticktimer_tick_all (void);

#endif
\ifndef\uuuuuh
#定义计时器
#包括
#包括
#包括
#包括
#包括
#定义计时器\u停止0x00
#定义计时器\u未补偿0x00
#定义计时器\u运行0x01
#定义计时器\u补偿0x02
结构计时器{
u_int64_t tm_tick_间隔;
最后一次勾选;
总数为64;
未签名的ticks\u总数;
void(*勾选)(结构勾选计时器*);
无符号字符标志;
int