This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

使用CLT优化C6000系列DSP程序

使用CLT优化C6000系列DSP程序

1         C6000 DSP内核CACHE机制

当前,高性能DSP内核C66系统的存储器框图如图所示。

 

存储器被分成了三级:第一级是L1,包含数据存储器(L1D)和代码存储器(L1P);第二级是代码和数据共用存储器(L2以及MSMC SRAM);第三级是外部存储器,主要是DDR3存储器。L1PL1DL2CACHE功能分别由相应的L1P控制器、L1D控制器和L2控制器完成。

通常我们会把L1P配置成CACHE,而L1P的空间是有限的(32KB),当CPU发出取指命令,首先会从L1P里查找,如果L1P找不到,则到下一级cache或者memory里查找,依次类推,当找到需要的地址,则将其填入L1P里,CPU从中读取执行,若L1P当前位置已有内容,则需要将其置成无效后填入新的数据。

如果代码在内存排布不合理时,可能会发生反复的从L1P里置换出旧的CACHE内容,填入新的CACHE内容,如下图中的极端情况

在该例中A函数中FOR循环反复调用B函数,而A,B,C三个函数在内存地址的分布上,与32KB 边界的偏移地址是一样的,因此,A,B,C将映射L1P里同一个CACHE位置;当执行A时,CPU需要把A函数调入到L1P中,当执行到B时,则需要将L1PA函数位置无效,调入B,当B返回时,又需要将B无效,调入C函数,C函数返回时再调入B函数……这样反复的对CACHE操作将大大的降低程序的执行效率。

那么,我们应该如何解决该问题?最好的解决方法则是将A, B, C在内存中连续排放,这样,A,B,C反复调用时,对CACHE的操作次数将降到最低,能够有效的提高执行效率。

2         内存优化工具 Cache Layout Tools

通过上述机制可以看到,内存优化主要通过分析函数调用关系和其在内存的分步。由于用户代码日益复杂,人工分析代码调用关系和地址排布需要花费大量的时间。因此,TI提供了一整套内存优化工具  (Cache Layout Tools, 简称 CLT) 来帮助用户轻松快捷地解决该问题。

该工具的原理是在用户进行程序编译时打开生成分析信息选项,编译器会自动加入分析记录代码到用户程序里,而后用户在TI DSP simulator或者DSP芯片上运行该可执行文件,内置的分析代码会自动记录用户的函数调用关系及调用次数。运行的案例越多,则记录的信息会更详细,优化的效果也就越好。

在得到函数运行时信息以后,就可以使用编译器工具对其进行分析,生成函数排布的顺序,最后将此排布顺序输入到编译器里重新编译原代码,生成的可执行文件就已经优化过内存排布,具体的操作可以参照以下实例。

3         实例教程

1. 该实例主要由三个C文件组成,如下
main.c:
• defines main()
• main() calls rare() once
• main() calls main.c:local() 10 times
• defines static local()
• main.c:local() calls lots() 20 times
lots.c:
• defines lots(); globally visible
• lots() calls lots.c:local() 100+ times
• defines lots.c:local()
rare.c:
• defines rare(); globally visible

实例中使用DSP计数器 TSCL来统计cycle数,不失一般性,子函数放在sub目录下。

 2.  编译代码
使用TI编译器对该实例进行编译,为了产生用于profile的信息,需要在编译时增加 -- gen_profile_info 选项。在本例中,可在命令行下运行Compile.bat文件,cl6x的具体参数可以参考spru186和spru187两篇文档,一般可以在编译器的安装目录下找到他们,如C:\Program Files (x86)\Texas Instruments\C6000 Code Generation Tools 7.3.9\doc。编译成功完成后,命令行输出如下图

 

 同时在目录下生成OBJASM文件,这个和我们的实验关系不大,可以不用关注。

OUT文件是一会需要下载到芯片里运行的可执行文件,而MAP文件用于帮助我们定位profile信息存放的内存地址。

3.  获取profile信息

打开MAP文件,可以找到.ppdata段的内存地址,这个地址就是profile信息存放处,在例子中

.ppdata    0    0081fecc    00000034     UNINITIALIZED

.ppdata段位于0x0081fecc这个地址,长度是34byte

启动CCSv5,连接EVM板,下载OUT文件到DSP上,在main函数末尾加上调试断点,可以让程序到这里停住(实际上,在用户代码中,可以把断点设置在需要的任何地方,profile的信息是实时更新的)。

 

运行该程序,到达断点后,在View菜单里打开memory browser,将地址设定为0x0081fecc, 可以读到.ppdata的信息,参考以下步骤将其存到工程目录下。

1)      选取save memory

 

2)      存放路径

 

3)      确定数据地址和长度,如下图

4.  打开刚才存下的DAT文件,注意到文件头的数据长度是以WORD数目为单位的,我们需要以BYTE数目为单位,如

1651 9 81fecc 0 d 1

修改为

1651 9 81fecc 0 34 1

5.    运行Analysis.bat里的命令,对刚才的运行profile信息进行分析,得到优化后的CMD内存排布文件,该文件内容如下,用户可根据自己的程序进行修改

Generate_pdatfile -le ppdata.dat pprofout.pdat

如果是大端,则将-le选项改为-be选项。

pdd6x pprofout.pdat -eCLTTutoirial.out -o=pprofout.prf

cl6x --abi=coffabi -o2 -mv64+ --include_path="C:\Program Files (x86)\Texas Instruments\C6000 Code Generation Tools 7.3.9/include" --use_profile_info=pprofout.prf --analyze=callgraph  main.c .\sub\lots.c .\sub\rare.c

clt6x main.csv lots.csv rare.csv -o pfo.cmd

6.    运行Recompile.bat利用上一步输出的pfo.cmd重新编译输出优化后的OUT文件,cache优化到此完成。

7.    对比前后结果,未优化时cycle数为171843,优化后为161883,在该实例中,利用cache layout tools可以节省约1cycle