【实时性迷思】CPU究竟跑的有多快?
【说在前面的话】
相对人的感官来说CPU跑的太快了——即便是人们常常用来描述时间短暂的“一眨眼功夫”对CPU来说也是及其“漫长”的好几百毫秒了——仔细想想有几个人能在一秒钟内连续眨十次眼睛呢?正因为如此,即便是超级循环里面顺次执行的多个任务,在人类看来也往往是“一瞬间就执行完了”。那么CPU究竟跑的有多快呢?是很快、非常快还是快得不得了?如果我们继续站在人类的视角考虑这个问题,其抽象程度无异于思考“无穷大究竟是多大”。
【第一个参考点】
“1MHz就是 1us”
“1MHz就是1us”是一个基准概念,通过修改思考方式,我们就可以利用它快速而有效的解决很多实际问题。作为练习,我们来尝试依次快速的回答以下几个问题:
假设每个时钟脉冲都对应一个指令周期:
已知系统频率是1MHz,请问1us内有几个指令周期?
已知系统频率是12MHz,请问1us内有几个指令周期?
已知系统频率是11.3728MHz,请问1us内有几个指令周期?
已知系统频率是500KHz,请问1us内有几个指令周期?
很显然,如果你试图首先计算出系统周期:
再用1us去相除:
这个过程已经慢了。
由于主流的微控制器其指令集中大多是单周期指令,我们不妨假设所有指令都是单指令周期的,这样1个指令周期就对应一条指令;
假设每条指令都是2个字节大小(16位指令);
这样,1ms时间内1MHz的系统可以运行大约2KB的代码,一个12MHz的系统可以运行24KB的代码,依次类推。
那么2KB是什么概念呢?如果你平时有留意编译后的代码尺寸,2KB大约是一个基础驱动库的尺寸,可以包含一个USART的驱动或者实现电源管理;而24KB几乎是一个小型工程应用的尺寸了。
中断处理程序“执行的是不是足够快”?
“丢中断的风险究竟有多大”等等?
使用中断接收外设数据的时候会不会发生丢失?
可以肯定的是,这种忽略循环和条件分支的评估方法几乎是一个代码的最差情况,也就是说,在1MHz的系统中对于一个1KHz的毫秒中断,中断处理程序越接近2KB,就说明系统越可能“丢中断”。
在这种情况下,除非你通过编译器提供的等效汇编代码仔细的计算过实际的周期数,或者是通过perf_counter这样的工具实际测量过代码的周期消耗——确信时间上处理周期不会大于1ms且这期间不会存在其它中断处理程序,否则你的中断处理程序还是比2KB越小越好。
【一个真实的案例】
在一个72MHz的Cortex-M3/M4系统下,使用中断模式来接收串口数据,波特率为115200的情况下:
最大允许屏蔽中断多长时间?
中断处理程序允许的理论最大安全尺寸是多少?
【结语】
如果你喜欢我的思维、觉得我的文章对你有所启发,
请务必 “点赞、收藏、转发” 三连,这对我很重要!谢谢!
欢迎订阅 裸机思维