请问clock()函数的返回值clock ticks,频率是18.2hz,与cpu主频无关吗?

icegrape 2006-06-06 09:05:28
在dos,turbo 2.0下编程
想精确测试c代码运行时间,但对于时间函数不是很熟悉
查资料,尝试用INT 8定时器中断,请问这个约55毫秒(1/18.2秒)产生一次中断,这个频率
与所运行系统的cpu主频有关系吗?是不是对于cpu 300M还是2.0G的计算机都是一样的呢?

还有clock()函数中统计的滴答数,其频率也是18.2hz吧?

是不是delay()函数的延迟与cpu主频有很大关系?还是和编译器有关呢?因为我在dos系统下用tc2.0
,可是挺人说同系统下,用tc3.0的话,delay好像比较准?这到底是怎么回事呢?

对于这些概念是在很含糊,希望大家多多指教^_^
...全文
797 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
icegrape 2006-06-07
  • 打赏
  • 举报
回复
是不是说如果我想实现精确定时的话,还是应该直接对8254定时器编程呢?
但是我的程序中还有别的中断,其中断处理字程序中都会有disable(),这样会导致
所有硬件中断被禁止吧?这时是不是定时器中断也会不起作用呢?使得时间不准确呢?

megaboy 2006-06-07
  • 打赏
  • 举报
回复
int8 是时钟硬件产生的中断,中断控制器(intel 8259)被映射到系统的预定义中断中,DOS系统每隔55ms产生一次INT8 的中断。与cpu频率无关
----------------------------------------------------------------------
这个不是时钟,是8254定时器,时钟(RTC)是连在8259的IRQ8上的。这也不是DOS的行为,而是BIOS在启动的时候已经为8254的定时器0初始化为每隔大约55ms产生一次中断,DOS只不过没有修改定时器0中的计数器。



这个频率
与所运行系统的cpu主频有关系吗?是不是对于cpu 300M还是2.0G的计算机都是一样的呢?
-----------------------------------------------------------------------
没有关系。这个大约55ms的间隔是由8254的定时器0产生的,8254由外部频率经过内部分频每隔836ns产生一个脉冲,用这个脉冲驱动三个定时器的计数器进行计数,定时器0被BIOS定义在工作方式3上,计数器写入0,因此每隔65536x836ns(结果就是大约55ms)的时间段产生一次IRQ0中断。整个过程与CPU无关。


还有clock()函数中统计的滴答数,其频率也是18.2hz吧?
----------------------------------------------------
许多编译器是这样,但并非每个系统都如此。c90规定了一个常数宏CLK_TCK,而c99则变成了CLOCKS_PER_SEC,两者是一样的。通常来说,这两个宏的值是18.2。不过,偶认为定义这样一个“常数”非常勉强,因为这个“常数”值并不是一个强制性的规定,它基于这样一个假设:不会有人去修改8254的定时器0。但事实是,即使在同一系统下,8254定时器0的计数器也常常被其它应用随意修改,基于这样一个“常数”编写程序,不同时间可能会产生不同的结果。
megaboy 2006-06-07
  • 打赏
  • 举报
回复
是不是说如果我想实现精确定时的话,还是应该直接对8254定时器编程呢?
--------------------------------------------------------------
是的。不过,8254不是唯一的定时源,61h的PB4位也可以用于定时,传统上,PB4位的状态每隔15微秒翻转一次,这是由8254的定时器1提供的,为DRAM刷新提供定时信号,这个信号被反馈到这一位。只要设置一个变量,PB4每次翻转都计数一次,也能达到定时的目的。但是,这个PB4的刷新时间在不同的OS下似乎不同,DOS下是通常的15微秒,而xp下却比15微秒快了几倍!害我重新写了一个程序,原因到现在还没弄清楚。



但是我的程序中还有别的中断,其中断处理字程序中都会有disable(),这样会导致
所有硬件中断被禁止吧?这时是不是定时器中断也会不起作用呢?使得时间不准确呢?
------------------------------------------------------------------------
disable()就是汇编中的cli,它只会禁止可屏蔽中断,不会禁止所有硬件中断。8254提供的中断属于可屏蔽中断,disable()会把8254也禁止掉(但不能禁止61h的PB4)。进入中断处理程序后是否开放IF取决于程序的需求以及设计者的良好素质,否则只会在运行iret之后IF才会恢复原来的状态。



“8254定时器0的计数器也常常被其它应用随意修改”这个随意修改是不是一般是指用户自己编程造成的呢?还是系统本身执行某些任务的时候会修改呢?
------------------------------------------------------------------------
都有可能。



如果我现在在纯dos下,dos是单线程,我现在可以确保没有其他人编程用到过8254,那么是不是这时间结果应该比较稳定呢?
--------------------------------------------------------------------
这是不可能的,特别是在DOS中,不可能阻止别人的中断勾连,只能祈求god bless you了。你的中断向量随时可能被人替换,如果设计者没有什么素质,不进行中断链接或者没有在你期望的时间链接你的中断处理程序,那么定时肯定要受到影响的。

此外,作为题外话,纠正一下你的说法,dos是没有线程的概念的,但有进程的概念,虽然是单任务,但具有多进程的某些特征,它有进程控制,但没有进程调度。
icegrape 2006-06-07
  • 打赏
  • 举报
回复
……即使在同一系统下,8254定时器0的计数器也常常被其它应用随意修改,基于这样一个“常数”编写程序,不同时间可能会产生不同的结果。
-----------------------------------------------------------------------------------
“8254定时器0的计数器也常常被其它应用随意修改”这个随意修改是不是一般是指用户自己编程造成的呢?还是系统本身执行某些任务的时候会修改呢?
如果我现在在纯dos下,dos是单线程,我现在可以确保没有其他人编程用到过8254,那么是不是这时间结果应该比较稳定呢?
happytang 2006-06-06
  • 打赏
  • 举报
回复
函数名: delay
功 能: 将程序的执行暂停一段时间(毫秒)
用 法: void delay(unsigned milliseconds);
程序例:
/* Emits a 440-Hz tone for 500 milliseconds */
#include <dos.h>

int main(void)
{
sound(440);
delay(500);
nosound();

return 0;
}
当然跟cpu主频有关系,也就是执行一条指令的时间有关
与编译器也有关,就是编译器生成代码指令不同造成的
happytang 2006-06-06
  • 打赏
  • 举报
回复
int8 是时钟硬件产生的中断,中断控制器(intel 8259)被映射到系统的预定义中断中,DOS系统每隔55ms产生一次INT8 的中断。与cpu频率无关

还有clock()函数中统计的滴答数,其频率也是18.2hz吧?
也就是中断次数,当然与cpu也无关
icegrape 2006-06-06
  • 打赏
  • 举报
回复
是说不仅与cpu主频没有关系,而且确定对于任何计算机都是55毫秒吗?
那么delay()呢?这个与cpu频率有关吗?
yuanchuang 2006-06-06
  • 打赏
  • 举报
回复
请问这个约55毫秒(1/18.2秒)产生一次中断,这个频率
与所运行系统的cpu主频有关系吗?
-----------
可以明确的说,没有关系,呵呵

69,371

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧