Chinaunix首页 | 论坛 | 博客
  • 博客访问: 412912
  • 博文数量: 44
  • 博客积分: 4980
  • 博客等级: 上校
  • 技术积分: 1035
  • 用 户 组: 普通用户
  • 注册时间: 2007-01-09 20:39
个人简介

偶尔编程的胖子 40岁之后还能坚持学习

文章分类

全部博文(44)

文章存档

2023年(12)

2022年(2)

2011年(1)

2010年(6)

2009年(1)

2008年(22)

我的朋友

分类:

2008-07-30 19:12:36

当有些厂家的 ARM7 内核可以跑到75MHz 的时候,这种高速度真的让人很兴奋:32bit 的 MCU 价钱仅仅在 25 元人民币左右,集成了各种外设的整体性能却直逼当年的 80486 PC 整机,让人感慨万千。

但是,在高速的背后,却有些鲜为人知的细节。在看完厂家的产品说明书后,有人不禁产生了一个疑问:集成的 MCU 真的可以跑这么快吗?那些存储器的等待周期怎么来理解呢?

----------------------------------------------------------------------------------------------------------------------------------------

在 75MHz 下,ARM7 的指令周期为 13.333ns,即 CPU 内核每 13.333ns 内必须要取到一条指令数据并且还要执行完它,这就可以估计出,存储器的访问周期大约是 6~8 个纳秒左右。这样的话,对存储器的要求是非常高的,代价也是高昂的,更要命的是: 由于 FLASH 存储器的生产工艺限制,无法达到这么快的速度!怎么办?

为了解决这个问题, 内核使用流水线架构,使用并行技术。例如:在执行一条指令的同时,又取出下一条指令的数据,让指令数据在执行它之前就准备好。如此一来,对存储器的速度要求就降低很多,按照上面的 75MHz 来说,存储器的访问周期只要达到 13.333ns 就够了。

对于 SRAM 存储器来说,达到这个要求一点也不困难,但是它的工艺复杂,成本相当高,而且一断电就会丢失数据,所以 MCU 内的 SRAM 容量总是很小的,大多数只用来存储变量数据和提供给堆栈来使用。MCU 内又集成了不怕断电,成本又低的 FLASH 存储器,来存放程序代码。但是 FLASH 存储器是无法达到这个苛刻的速度要求的,它就是以最快的速度来运作,访问周期大约也只能勉强提升到 30 ~ 40 多纳秒左右。如此一来,集成了 FLASH 存储器的 ARM 内核想要全速跑代码还是存在问题,如何解决呢?

各厂家不约而同地使用了一个最简易的办法 : 拓展数据线宽度。就是将 FLASH 存储器的数据线拓宽到 128bit 甚至 256bit 。这样的话,在 FLASH 存储器一个访问周期内,MCU 利用总线管理器可以读取 16 个字节或 32 字节(即 4 条或 8 条 ARM 指令)的代码数据供给 ARM 内核执行。因此,ARM 内核在执行这几条指令的期间,总线管理器可以让FLASH 存储器从容地用一个存储器周期提供下 4 条或 8 条指令数据,如此下去,似乎 ARM 内核就可以全速跑 FLASH 中的代码了。

这是个很巧妙的方法,但不是完美的,因为这种假设 CPU 代码一路跑下去不拐弯的情况在现实中是不存在的。各种分支、跳转、调用等意外情况将会使代码执行顺序被打乱,不能就指望一条一条的代码会安排的整整齐齐一直顺利执行下去。

一旦出现这种情况,总线管理器在 FLASH 的本次访问周期内提供的几条指令数据就作废了。为了获得正确的下一条指令代码,总线管理器要重新访问 FLASH 存储器的新地址。但是,由于 FLASH 本身速度的问题,无法及时提供指令数据,此时总线管理器会强制 ARM 内核处于等待状态,直到 FLASH 存储器完成其一个完整的访问周期,其中的指令数据被正确读取出来后,总线管理器才会恢复 ARM 内核的运作,并提供新的代码数据给内核执行,这就表示本来可以跑 3~4 条指令的时间,内核却是被强制暂停的,时间被浪费掉了,这就是存储器访问等待周期的由来。

假设一种极端情况:FLASH 存储器中的每条正常指令后面都是一条跳转指令,那么内核在每执行一条指令后,就会处于等待状态大约有 3~4 指令的执行时间。估计一下,内核此时的执行速度仅仅是全速的 1/3 或 1/4 左右。如果按照主频 75MHz 来算,此时的运作效率大概和全速 20MHz 的内核相当。呵呵,很尴尬的结果,是不是?

上面假设的极端情况是极其难遇的,但是:用 C 语言写出来软件编译后,在 10 ~ 20 条指令里面就有一条跳转的可能性是极高的!照此来估算的话,内核的运作速度会比全速的效率低 1/10 至 1/5 左右。 按照 75MHz 的内核工作频率来算,它可能仅仅只能跑到 60MHz 左右。假如软件中采用了大量的 32bit 整型常数的话,效果和上述极端的情况是一样的:即为了获取当前 FLASH 访问周期内没有的数据,总线管理器必须抛弃当前的代码数据,并重新启动一次访问周期来读去整型常数数据,然后再重新启动一次访问周期来获得刚才被抛弃的、却又要需要继续执行的代码。

由此可以看出,软件编写的好坏对 ARM7 内核的运行效率影响是多么的巨大!

 从一些厂家使用了 ARM7 MCU 为主控制器的产品来分析,许多需要高速运行和需要明确指令周期的代码段被重新加载到 MCU 中的 SRAM 中来运行,SRAM 存储器可以达到单周期访问,即完全配合了 ARM7 内核的高速度来全速运行。而在更高级的 ARM 内核中,采用了 Cache 存储器,尽可能地避免上述的低效的、却又很无奈的行为。

所以,采用了 ARM7 为内核的 MCU ,参数表上常常标明 SRAM 的访问速度为全速,等待周期为 0,而 FLASH 却没有明确说明速度是多少,只是告诉你 CPU 内核在跑到什么频率段的时候,FLASH 存储器的等待周期应该设置为几个周期,这就是原因了。

由此看来,仅仅看 ARM7 的内核标称运行速度来判断你的代码能跑多快是不正确的。你需要分析很多综合性的情况才能大概地了解自己写的代码可以大概跑到什么速度。想要再提高,呵呵!努力吧,好好整理自己的软件架构,来配合以 ARM7 为内核的 MCU,这样也许可以达到你的期望值哦!

阅读(1179) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~