在C中使用硬件定时器

好的,所以我有一些C代码来执行math运算,几乎可以花费任何时间(取决于提供给它的操作数)。 我想知道是否有一种方法来注册某种方法,这将每n秒调用一次,可以分析操作状态,即当前正在进行什么迭代,可能使用硬件定时器中断或什么?

我问这个的原因是因为我知道实现这个的通用方法是跟踪variables中的当前迭代; 比如说一个叫做progress的整数,并且在代码中有这样的IF语句:

 if ((progress % 10000) == 0) printf("Currently at iteration %d\n", progress); 

但是我相信一个mod操作需要相当长的时间才能执行,所以从优化的angular度来看,在一个循环内部运行很多次,这个循环会令我感到恐惧。

所以我觉得有一个外部的方式来表示一个进展印刷是好的和高效的。 有没有什么好的方法来实现这一点,或者是简单的“模块检查”是最好的(就优化而言)?

我会去与国防部检查,但也许用减法:-)

 icount = 0; progress = 10000; /* ... */ if (--progress == 0) { progress = 10000; printf("Currently at iteration %d0000\n", ++icount); } /* ... */ 

虽然mod操作通常很慢,但是编译器应该能够对这个问题进行优化和预测,并且只能错误地预测一次10000个ifs,将一个mod操作和20个周期(对于错误预测)进行烧写,很好。 所以你试图每10,000次迭代优化一个mod操作。 当然,这是假定你正在一个现代的典型CPU上运行它,而不是一些未知规格的嵌入式系统。 这应该甚至比有一个计数器变量更快。 建议:在没有定时代码的情况下进行测试,如果确实存在问题,可以找出一个复杂的解决方案。

不成熟的优化是万恶之源。 -Knuth

mod与分割的速度差不多,现在大部分的CPU都是大约5-10个周期……换句话说,几乎没有任何东西,比乘法/加/减法慢,但是还不足以真正担心。

然而,如果你正在另一个线程或类似的工作中,如果你在一个unixish系统上有timer_create()或者在linux上使用timerfd_create()会更容易,

但是对于单线程来说,只要把它放在足够的位置就行了。

使用alarm setitimer定期提升SIGALRM信号。

 struct itimerval interval; void handler( int x ) { write( STDOUT_FILENO, ".", 1 ); /* Defined in POSIX, not in C */ } int main() { signal( SIGALRM, &handler ); interval.it_value.tv_sec = 5; /* display after 5 seconds */ interval.it_interval.tv_sec = 5; /* then display every 5 seconds */ setitimer( ITIMER_REAL, &interval, NULL ); /* do computations */ interval.it_interval.tv_sec = 0; /* don't display progress any more */ setitimer( ITIMER_REAL, &interval, NULL ); printf( "\n" ); /* done with the dots! */ } 

请注意,只有一些功能可以调用内部handler 。 他们被列在这个页面的中途。 如果您想为sig_atomic_t打印输出任何东西,请通过sig_atomic_t变量来完成。

你可以有一个迭代的全局变量,你可以从外部线程监视。

 While () { Print(iteration); Sleep(1000); } 

尽管你可能需要注意数据竞赛。