对于CPU的外部事件进行检测,究竟是采用轮询还是中断,并没有一个正确的答案。在硬件支持外部中断的情况下,中断仅仅只是又多了一种选择的余地。如果系统没有采用RTOS,那么在应用程序执行时候,为了避免因为主程序执行的时间过长而导致其它输入事件的丢失,则中断可能是最好的方式。
在轮询系统中,即便是没有输入事件,由于仍然需要周期性的读取外部输入设备的状态,这会导致不必要的CPU开销。同样的系统如果采用中断驱动,当外部输入设备空闲的时候则不会存在任何CPU的开销。
然而,相比轮询而言,中断驱动带来的开销情况变化多端。如果每隔10ms查询一下键盘,当没有按键按下时候,花费0.1ms;若按键有按下,检测按键并将事件投放到队列中,将花费0.3ms,则按键读取产生的开销为1%到3%之间。(0.1/10 = 1% 0.3/10 = 3%)即使系统中还有其它的任务在执行,读取输入带来的开销差不多也只在3%。考虑这样一个情形: 用户按下按键,并保持300ms时间。在这段时间中,按键事件被检测到并且应用任务也得到了通知。应用任务可能启动一个时间—关键(time-critical)工作,如启动电机并调节到特定的速度。在这项工作完成后,系统再次进入250ms的沉寂状态。在系统处理这些工作时候,按键仍处于按下状态,它带来的处理开销依旧是3%。这种相似的情况也出现在移动装置的处理中,如鼠标。在鼠标运动被处理时候,鼠标看起来依旧在移动。
现在,来考虑中断驱动的情况。如果按键输入没有滤波处理,则不得不需要通过禁止中断或在一个确定的周期内忽略中断,以达到消抖的目的。硬件可能可以通过或者不允许软件来禁止掉中断。禁止掉中断而不丢失事件,这是不可能的。在这种情况下,如果按键没有滤波,则可能产生抖动,当按键按下事件发生的时候,这将导致在很短的时间内连续产生多个中断。由这些中断带来的开销是不确定的。更重要的是,这可能带来最坏的时间开销。当按键按下时候,处理器必须专心的去响应这个请求。类似地,如果每次鼠标位置变化都产生一个中断,处理器将不得不对每次微小的位置变化产生的中断进行处理,而不是像轮询系统中那样,以一个较低的频率去读取鼠标的位置。这里,需要对鼠标的分辨率以及处理器处理能力的吞吐力作一个折衷。从这一点来看,对处理要求所需的峰值时间作出一个估计是非常有必要的。
选择轮询还是中断的另外一个因素是系统是否容易调试。在一个轮询系统中,不用担心一个连接到高中断优先级的设备会长时间阻塞低优先级的设备,进而导致低优先级设备产生的事件丢失。
若选择了轮询方式,一个需要考虑的问题是轮询周期。这点很重要,因为过短的轮询周期将会导致高的CPU开销,而过长的轮询周期则有可能遗漏掉持续时间比较短的事件。 |