好的,所以我有一些C代码来执行数学运算,这几乎可以花费任何时间长度(当然,取决于提供给它的操作数)。我想知道是否有一种方法可以注册某种方法,每个 n 秒可以调用它来分析操作的状态,即它当前处于何种迭代状态,可能使用硬件定时器中断什么的?
我问这个的原因是因为我知道实现它的常用方法是跟踪变量中的当前迭代;比方说,一个名为progress
的整数,在代码中有这样的IF语句:
if ((progress % 10000) == 0)
printf("Currently at iteration %d\n", progress);
但是我认为mod操作需要相对较长的时间才能执行,所以从优化的角度来看,将它放在一个循环中的想法将会让我感到很多次。
因此,我感觉有一种外部方式来表示进度打印是好的和有效的。有没有很好的方法来执行此操作,或者简单的“模式检查”是最好的(在优化方面)?
答案 0 :(得分:4)
我会使用mod检查,但可能会使用减法: - )
icount = 0;
progress = 10000;
/* ... */
if (--progress == 0) {
progress = 10000;
printf("Currently at iteration %d0000\n", ++icount);
}
/* ... */
答案 1 :(得分:1)
虽然mod操作通常很慢,但编译器应该能够很好地优化和预测这一点,并且只能错误地预测10'000 ifs,烧毁一个mod操作和~20个循环(用于错误预测)它,这很好。所以你试图每10'000次迭代优化一次mod操作。当然,这假设您在现代和典型的CPU上运行它,而不是某些具有未知规格的嵌入式系统。这甚至应该比具有计数器变量更快。 建议:使用和不使用计时代码进行测试,如果确实存在问题,请找出复杂的解决方案。
过早优化是万恶之源。 -Knuth
答案 2 :(得分:1)
mod与分区的速度大致相同,在大多数CPU上这些天意味着大约5-10个循环...换句话说几乎没有什么,比乘法/加/减慢,但不足以真正担心。 / p>
然而,如果你正在另一个线程或类似的东西中工作,你想要避免刺激循环旋转是正确的,如果你在一个unixish系统上有timer_create()
或在linux上更容易使用timerfd_create()
但是对于单线程,只要把它放进去就足够了。
答案 3 :(得分:1)
使用 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
内调用。它们被列在this page的中途。如果您想为更高级的打印输出进行任何沟通,请通过sig_atomic_t
变量进行。
答案 4 :(得分:0)
您可以为迭代创建一个全局变量,您可以从外部线程监视它。
While () {
Print(iteration);
Sleep(1000);
}
您可能需要注意数据竞赛。