TI C6000系列DSP_tic6000系列dsp
TI C6000系列DSP由刀豆文库小编整理,希望给你工作、学习、生活带来方便,猜你可能喜欢“tic6000系列dsp”。
第二章 基于TI C6000系列DSP的C /C++程序优化技术
2.1 TMS320C6000 处理器介绍
TM S320C6000 是 TM S320 系列产品中的新一代高性能DSP 芯片,共分为两大系列。其中定点系列为TM S320C62xx和TM S320C64xx;浮 点 系 列 为TM S320C67xx。由于 TM S320C6000 的开发主要面向数据密集型算法 ,它有着丰富的内部资源和强大的运算能力 ,所以被广泛地应用于数字通信和图像处理等领域。
C6000 系列 CPU 中的 8 个功能单元可以并行操作 ,并且其中两个功能单元为硬件乘法运算单元 ,大大地提高了乘法速度。DSP 采用具有独立程序总线和数据总线的哈佛总线结构 ,仅片内程序总线宽度就可达到256 位 ,即每周期可并行执行 8 条 32 位指令;片内两套数据总线的宽度分别为 32 位;此外 ,DSP 还有一套32 位DMA 专用总线用于传输。灵活的总线结构使得数据瓶颈对系统性能的限制大大缓解。C6000 的通用寄存器组能支持 32 位和 40 位定点数据操作 , 另外C67xx 和 C64xx 还分别支持 64 位双精度数据和 64 位双字定点数据操作。除了多功能单元外 ,流水技术是提高 DSP 程 序 执 行 效 率 的另一 主 要 手 段。由于TM S320C6000 的特殊结构 ,功能单元同时执行的各种操作可由VL IW 长指令分配模块来同步执行 ,使 8 条并行指令同时通过流水线的每个节拍 ,极大地提高了机器的吞吐量。
2.2 C6000 软件开发流程
图 2-1为 C6000的软件开发流程图。图中阴影部分是开发 C代码的常规流程 ,其他部分用于辅助和加速开发过程。
图2-1软件开发流程
C/ C + +源文件首先经过C/ C + +编译器转换为 C6000汇编源代码。编译器、优化器(optimizer)和交叠工具是 C/ C + +编译器的组成部分。编译器使用户能一步完成编译、汇编和连接;优化器调整合修改代码以提高 C程序的效率;交叠工具把 C/C + +语句和对应的汇编语句交叠列出。
汇编源代码再经过汇编器(A embler)翻译为机器语言目标文件。机器语言是基于通用目标文件格式(Co mmo n Object File Format ,CO FF)的。连接器(Linker)连接目标文件 ,生成一个可执行文件。它要完成地址的重分配(Relocatio n)和解析外部引用(Resolve External References)。
得到可执行文件之后就可以进行调试。可用软件仿真器(Simulator)在 PC机上对指令和运行时间进行精确仿真;用 XDS硬件仿真器(Emulator)在目标板上进行调试。调试通过后即可下载到目标板进行独立运行。
2.3程序优化流程及方法
2.3.1 程序优化阶段
由于 DSP应用的复杂度 ,在用 C语言进行 DSP软件开发时 ,一般先在基于通用微处理器的 PC机或工作站上对算法进行仿真 ,仿真通过后再将 C程序移植到DSP平台中。
所以 ,DSP的软件开发与优化流程主要分为 3个阶段 :C代码开发阶段;C代码优化阶段;手工汇编代码重编写阶段。如图2-2所示。
在图2-2中 ,第一阶段 :没有 C6000知识的用户能开发自己的 C代码 ,然后使用 CCS中的代码剖析工具 ,确定 C代码中可能存在的低效率段 ,为进一步代码优化做好准备。第二阶段 :C代码优化阶段。在这个阶段 ,主要利用intrinsics函数以及编译器编译选项来提高代码的性能。优化后利用软件模拟器检查代码的效率 ,如仍不能达到期望的效率 ,则进入第三阶段。第三阶段 :写线性汇编优化。在这个阶段中 ,用户把最耗费时间的代码抽取出来 ,重新用线性汇编写 ,然后使用汇编优化器优化这些代码。在第一次写线性汇编时 ,可以不考虑流水线和寄存器分配。然后 ,提高线性汇编代码性能 ,往代码中添加更多的细节,如分配寄存器等。由于这一阶段所需的时间要比第二阶段多,所以整个代码的优化尽量放在第二阶段来完成 ,而少使用线性汇编代码优化。
图2-2程序优化流程
2.3.2 C/ C + +代码优化方法
为了使 C/ C + +代码获得最好的性能 ,可以使用编译选项、件流水、联函数和循环展开等方法来对代码进行优化 ,以提高代码执行速度 ,并减小代码尺寸。
2.3.2.1 编译器选项优化
C/ C + +编译器可以对代码进行不同级别的优化。高级优化由专门的优化器完成 ,低级的和目标 DSP有关的优化由代码生成器完成。
图2-3为编译器、化器和代码生成器的执行图。当优化器被激活时 ,将完成图2-3所示的过程。C/ C + +语言源代码首先通过一个完成预处理的解析器(Parser),生成一个中间文件(.if)作为优化器(Optimizer)的输入。优化器生成一个优化文件(.opt),这个文件作为完成进一步优化的代码生成器(Code Generator)的输入,最终生成汇编文件(.asm)。
图2-3 C/ C + +优化编译流程
最简单执行优化的方法是采用 cl6x编译程序 ,在命令行设置O2和-O3选项编译 C/ C + +程序时 ,编译器就从程序中收集信息 ,尝试对程序循环做软件流水。
图2-4显示一个软件流水循环。图2-4中 A ,B , C ,D和 E表示 1次迭代中的各条指令;A1 , A2 , A3 , A4和A5表示一条指令执行的各阶段。循环中 ,一个周期最多可并行执行 5条指令 ,即图中阴影部分所示的循环核(Loop Kernel)部分。循环核前面的部分称为流水循环填充(Pipelined Loop Prolog),循环核后面部分称为循环排空(Pipelined Loop Epilog)。
图2-4软件流水循环
2.3.2.3 内联函数优化
通过下面的方法改进 C语言程序 ,可使编译出的代码性能显著提高 :(1)使用 int rinsics(内联函数)替代复杂的 C/ C + +代码;(2)使用字(word)访问存放在 32位寄存器的高16位和低 16位字段的数据;(3)使用双字访问存放在 64位寄存器的 32位数据(仅指 C64XX/ C67XX)。C6000编译器提供了许多内联函数 ,它们直接对应着 C62X/ C64X/ C67X指令可快速优化 C代码。这些内联函数不易用 C/ C + +语言实现其功能。内联函数用前下划线“_”特别标示 ,其使用方法与调用函数一样。
例如 C语言的饱和加法只能写为需要多周期的函数 : int sadd(int a ,int b){ int result;result = a + b;if(((a^b)&0x80000000)= = 0){ if((result^a)&0x80000000){ result =(a
result = _sadd(a ,b);要提高 C6000数据处理率 ,应使一条 Load/ Sto re指令能访问多个数据。C6000有与内联函数相关的指令 ,例如_add2(),_ mp yhl(),_ mp ylh()等 ,这些操作数以 16位数据形式存储在 32位寄存器的高位部分和低位部分。当程序需要对一连串短型数据进行操作时 ,可使用字 1次访问 2个短型数据 ,然后使用 C6000相应指令来处理数据。相似的在 C64x或 C67x中 ,有时需要执行 64位的 LDDW来访问两个 32位数据 ,4个16位数据 ,甚至 8个 8位数据。
2.3.2.4 循环展开
循环展开是改进性能的另一种 ,即把小循环的迭代展开 ,以让循环的每次迭代出现在代码中。这种方法可增加并行执行的指令数。当每次迭代操作没有充分利用 C6000结构的所有资源时 ,可使用循环展开提高性能。
有 3种使循环展开的方法 :(1)编译器自动执行循环展开;(2)在程序中使用 UN ROLL伪指令建议编译器做循环展开;(3)用户自己在 C/ C + +代码中展开。2.3.3 汇编优化
在对 C/ C + +代码使用了所有的 C/ C + +优化手段之后 ,如果仍然不满意代码的性能 ,就可以写线性汇编程序 ,然后用汇编优化器进行优化 ,生成高性能的代码。
2.3.3.1 写线性汇编
使用 C6000的剖析工具(Profiling Tool s)可以找到代码中最耗费时间的部分 ,就是这部分需要用线性汇编重写。线性汇编代码与汇编源代码相似 ,但是 ,线性汇编代码中没有指令延迟和寄存器使用信息。这样做的目的是由汇编优化器来为自己设定这些信息。
写线性汇编代码时 ,需要知道 :汇编优化器伪指令、影响汇编优化器行为的选项、TMS320C6000指令、线性汇编源语句语法、定寄存器或寄存器组、指定功能单元、代码注释等。2.3.3.2汇编优化器优化
(1)编排指令 ,最大限度的利用 C6000的并行能力;(2)确保指令满足 C6000的延迟要求(Latency Requirements);(3)为源代码分配寄存器。