大容量的存储器(如DRAM)访问速度受到限制,一般比CPU时钟速度慢很多;小容量的存储器(如SRAM)能提供快速的访问速度。因此很多高性能的处理器都提供分层的存储访问架构。
如图3所示,左右分别是平坦式存储器架构和2层cache的多层存储架构。在左边的架构中,即使CPU能运行在600MHz,但由于片内/片外存储器只能运行在300MHz/100MHz,CPU在访问存储时需插入等待周期。
图3 平坦式和层级式存储器架构
Cache部分工作状态说明
-
Cache hit(缓存命中):对于已经缓存的程序/数据,访问将引起缓存命中,缓存中的指令/数据立即送入CPU而无需等待。
-
Cache miss(缓存缺失):发生缺失时,首先通过EMIF读入需要的指令/数据,指令/数据在送入CPU的同时被存入Cache,读入程序/数据的过程CPU被挂起。
-
Cache flush(缓存命中):清空Cache已经缓存的数据。
-
Cache freeze(缓存冻结):Cache内容不再改变,发生缺失时,从EMIF中读入的指令包不会同时存入Cache。
-
Cache bypass(缓存旁路):Cache内容不再改变,任何程序/数据都将从缓存外存储器访问。
C6000的存储架构
C6000系列DSP在片内RAM和CPU之间提供两层Cache L1和L2,每层Cache又分为独立的程序Cache和数据Cache。其中L1是固定的,L2可以被重映射为普通片内RAM。
对程序/数据进行访问时,CPU首先到L1 Cache中寻找,命中则直接访问,如果产生缺失,则继续在L2Cache中寻找,如果还未命中,则到片内RAM或片外RAM中寻址数据。
图4 C6000 CPU的程序/数据访问流程
访问定位的规律
由图4可知,要保证CPU的存储访问效率,只有在CPU在大部分的访问都是只针对最靠近它的存储区时才有效。幸运的是,根据访问定位的规律,这一条可以保证。访问的定位规律表明程序在一个相对小的时间窗口对仅需要一个相对较小size的数据和代码。数据定位的两条规律:
优化cache性能
从访问定位规律出发,可总结出优化cache性能的一些基本准则:
段[1,6]
目标文件(.obj)的最小单位称为段,它是占据一个连续空间的代码块或者数据块。连接器的功能之一就是把段重定位到目标系统的存储器映像图中。所有段都可以独立重定位,用户可以把任一段置入目标存储器任一指定块内。
一个COFF文件包含三个默认段:.text、.data、.bss。用户还可以创建、命名、连接自己的段,也可以继续在各个段中继续划分子段。
在C/C++代码中,有两个预编译语句可用来将特定的代码或数据分配到指定的段中:
-
CODE_SECTION:为代码分配段。
-
DATA_SECTION:为数据分配段。
栈和堆[1,6]
栈(.stack)和堆(.heap)是为处理器运行时提供支持的两个存储区。
栈是由编译器在需要时分配的,不需要时自动清除的变量存储区。它用于存放局部变量、函数参数等临时数据。
堆用于动态内存分配。堆在内存中位于bss区和栈区之间。一般由程序员分配和释放,若程序员不释放,程序结束时有可能由OS回收。例如C中常用的malloc()函数就是在堆中开辟区间存放数据。
|