好文档 - 专业文书写作范文服务资料分享网站

TMS320C6678 Programmar Guider翻译

天下 分享 时间: 加入收藏 我要投稿 点赞

TMS320C6678 Programmar Guider

本文是对DSP程序优化的第2到4章的部分翻译,水平有限,不妥之处敬请原谅。

2 优化C/C++代码 2.1

写C/C++代码

本章描述了如何分析和裁剪你的代码,以确认你已经从C6000体系获得最好的性能。

2.1.1 数据类型小诀窍

当写C代码时遵循以下指导方针:

1. 避免编码int和 long类型一样大小,因为C6000编译器的long型为40bit; 2. 尽可能使用short数据类型为fixed-point乘法的输入,因为这种数据类型在

C6000里提供了最有效的16-bit乘法器。

3. 当有循环计数时,使用int或者unsigned int,而不要使用short和unsigned

short,以避免不必要的符号扩展说明。

2.1.2

分析C代码的性能

2.2 编译C/C++代码

编译工具提供了一个shell程序(cl6x),可以用来编译,汇编优化,汇编和单步链接程序。调用编译时输入:

cl6x [options] [filenames] [?z [linker options] [object files]]

2.2.1 编译选项

表2.1 代码关键性能避免选择的编译器选项

选项 -g/-s/ -ss 描述

这些选项限制了优化C语句的数量,导致较大的代码大小和较慢的执行速度 使软件流水线调试无效。用-ms2/-ms3代替来减少代码大小将在其它

代码大小的优化上禁用软件流水

总是使用-o2/-o3来最大化编译分析和优化,在性能和代码大小之间用

-o1/-o0

代码大小标志(-msn)来权衡

过时的。在3.00前,这个选项改善代码,但是在3.00后,这个选项

-mz

会降低性能增加代码大小。 表2.2 性能编译选项 -mu 选项 -mh§ -mhh

描述

允许投机执行。适当的填充量必须在数据内存中可用来确保正确执行,

这一般不是问题,但必须坚持如此。

描述了编译器的中断阈值。如果你知道在你的代码中没有中断发生,

-mi§

编译器可以在软件流水循环一个代码大小前后避免启用和禁止中断,

-mii

另外,高寄存器压力循环的充分利用有潜在的性能改进。 -mt§

?o3? ?op2§ ?pm?

使编译器能够使用假设,使编译器能与某些优化更先进。 代表最高水平的优化。各种循环执行优化,比如软件流水,展开,和

SIMD,各种文件级别特征也用于提高性能。

指定模块不包含提供给编译器的外部源码调用或者修改的函数和变

量。改善了变量分析和允许假设。

将源文件联合来执行程序层次的优化。

? Although ?o3 is preferable, at a minimum use the ?o option. ? Use the ?pm option for as much of your program as possible. § These options imply assertions about your application.

表2-3 编译器选项稍微降低性能和改善代码大小 选项 -ms0 -ms1

描述

主要优化性能,其次代码大小。可以用在所有的例程上,但最多用在

性能关键例程里。

禁止所有自动控制大小的内联(-o3允许)。用户指定的内联函数仍然

-oi0

允许。

表2.4中的选项都是控制代码选择的,结果是以较小的性能下降导致较小的代码大小。

表2.4 控制代码的编译器选项 选项

?o3? ?pm?

描述

代表最高水平的优化。各种循环执行优化,比如软件流水,展开,和

SIMD,各种文件级别特征也用于提高性能。

将源文件联合来执行程序层次的优化。

?op2 ?oi0 ?ms2?ms3

指定模块不包含提供给编译器的外部源码调用或者修改的函数和变

量。改善了变量分析和允许假设。

禁止所有自动控制大小的内联(-o3允许)。用户指定的内敛函数仍然

允许。

主要优化代码大小,其次性能。

表2-5描述的选项为信息,不影响性能和代码大小。

表2-5 信息的编译器选项 选项 -mw -k -s/-ss

描述

用这个选项来产生额外的编译器回馈,这个选项对性能和代码大小没

影响。

保持汇编文件,这样你就可以检查和分析编译器反馈。

在汇编中交叉C源码和优化评论。-s选项显示小性能下降;-ss选项显

示更严重的性能下降。

2.2.2 内存依赖(Memory Dependencies)

为了使你的代码最大有效化,C6000编译器安排了尽可能多的指令并行。为了安排并行指令,编译器在指令间必须决定依赖关系。依赖意味着一个指令必须在另一个指令之前发生;比如,一个变量在被调用前必须从内存中被加载。因此只有独立的指令才能并行执行,所以依赖性抑制并行性。

? 如果编译器不能决定两个指令是否存在依赖,那么它假设一个依赖项,

安排这两个指令循环计算完成第一个指令所需要的任何延迟。 ? 如果编译器可以决定这两个指令是独立于另一个的,那么可以安排并行。 编译器决定指令访问内存是否有依赖性是很难的,下面的技术帮助编译器决定哪个指令是没有依赖性的:

? 用restrict关键词指出一个指针是唯一的可以指向一个特定的对象的指

针声明的范围的指针。

? 用-pm选项,这个选项赋予编译器对所有的程序和模块全局访问和在排

除依赖性上允许它更激进。

? 用-mt选项,允许编译器使用假设消失依赖性。

2.3 2.4

Refining C/C++ Code Refining C/C++ Code

表2-10 Memory Access Intrisics

Type C compiler Intrisic _memd8(p)

Description

开始于地址p(存在内联)的非对齐访问double

型数据 开始于地址p的非对齐访问常量double型数据

开始于地址p的double型数据对齐访问 开始于地址p的常double型数据对齐访问 开始于地址p的unsigned int型数据的非对齐访

开始于地址p的常unsigned int型数据的非对齐

访问 开始于地址p的unsigned int型数据的对齐访问

_memd8_const(p) Double

load/store

_amemd8(p)

_amemd8_const(p)

_mem4(p)

Unsigned int load/store

_mem4_const(p) _amem4(p) _amem4_const(p)

开始于地址p的常unsigned int型数据的对齐访

开始于地址p的unsigned short型数据的非对齐

_mem2(p)

访问

开始于地址p的常unsigned short型数据的非对

Unsigned _mem2_const(p)

齐访问

short

开始于地址p的unsigned short型数据的对齐访

load/store _amem2(p)

开始于地址p的常unsigned short型数据的对齐

_amem2_const(p)

访问

指针p可以是任何类型。可是为了允许编译器正确的辨认指针别名,这些内联函数的指针参数p要正确的辨认指向对象的类型。比如,如果你想一次获得4个short型数据,那么在_memd8()里的p指向的类型必须是short。

2.4.2.1 Using Word Access in Dot Product(用字访问点积)

点积中用到了_mpy()和_mpyh()内联函数;

C编译器内联

int _mpy(int src1, int src2); int _mpyus(uint src1, int src2); int _mpysu(int src1, uint src2); uint _mpyu(uint src1, uint src2); int _mpyh(int src1, int src2);

Multiplies the 16 MSBs of src1 by the 16

描述

Multiplies the 16 LSBs of src1 by the 16 LSBs

ofsrc2 and returns the result. Values can be signedor unsigned.(src1的低16位跟src2的低十六位相乘,返回结果。返回值可以是signed或unsiganed)

int _mpyhus(uint src1, int src2); int _mpyhsu(int src1, uint src2); uint _mpyhu(uint src1, uint src2); int _(int src1, int src2);

int _mpyhuls(uint src1, int src2); int _mpyhslu(int src1, uint src2); uint _mpyhlu(uint src1, uint src2); int _mpylh(int src1, int src2); int _mpyluhs(uint src1, int src2); int _mpylshu(int src1, uint src2); uint _mpylhu(uint src1, uint src2);

MSBs

of src2 and returns the result. Values can be signed or unsigned.(src1的高十六位和src2的高十六位相乘,返回的值可以是signed或者unsigned)

Multiplies the 16 MSBs of src1 by the 16 LSBs of

src2 and returns the result. Values can be signed

or unsigned.(src1的高十六位和src2的低十六位相乘,返回值可以是signed或unsigned)

Multiplies the 16 LSBs of src1 by the 16 MSBs of

src2 and returns the result. Values can be signed

or unsigned.(src1的低十六位和src2的高十六位相乘,返回值可以使signed或unsigned)

2.4.2.3 Using Doubleword Access for Word Data (C64x/C64x+ and C67x Specific)

本节的Float Dot Product函数中用到了_itof(),_hi(),_lo()内联函数;

C/C++ Compiler

Description

Intrinsic float _itof(uintsrc); Longlong_itoll(uint src2, uint src1) uint _lo(double src);

将src的unsigned的比特数解释成float型。

通过重新诠释来创建一个新的long long型的寄存器组,src2是高(奇数)寄存器和src1为低(偶)寄存器。 从double寄存器组返回低(偶)寄存器

uint _lmbd(uint src1, 搜索由src1的最低位决定的src2的最左边的1或者0,uint src2); 返回的比特数目由改变的比特决定。 double _ltod(long src); 重新定义long 寄存器组为double寄存器组 uint _hi(double src); uint _lo(double src);

返回一个double寄存器组的高(奇)寄存器。 返回一个double寄存器组的低(偶)寄存器

TMS320C6678 Programmar Guider翻译

TMS320C6678ProgrammarGuider本文是对DSP程序优化的第2到4章的部分翻译,水平有限,不妥之处敬请原谅。2优化C/C++代码2.1写C/C++代码本章描述了如何分析和裁剪你的代码,以确认你已经从C6000体系获得最好的性能。2.1.1数据类型小诀窍当写C代码时遵循
推荐度:
点击下载文档文档为doc格式
3kom00wmxq7px008u2n1
领取福利

微信扫码领取福利

微信扫码分享