上述的三个阶段不是都必须经过,当在某一阶段获得了期望的性能,就不必进行下一阶段的优化。

1) 选用C编译器提供的优化选项

在编译器中提供了分为若干等级和种类的自动优化选项,如下:

● -o:使能软件流水和其他优化方法

● -pm:使能程序级优化

● -mt:使能编译器假设程序中没有数据存储混淆,可进一步优化代码。

● -mg:使能分析(profile)优化代码

● -ms:确保不产生冗余循环,从而减小代码尺寸

● -mh:允许投机执行

● -mx:使能软件流水循环重试,基于循环次数对循环试用多个方案,以便选择最佳方案。

根据实际编译的程序,选择合适的优化选项,进行源程序的优化。

2) 减小存储器相关性

为使指令达到最大效率,C64X编译器尽可能将指令安排为并行执行。为使指令并行操作,编译器必须知道指令间的关系,因为只有不相关的指令才可以并行执行。当编译器不能确定两条指令是否相关时,则编译器假定它们是相关的,从而不能并行执行。设计中常采用关键字const来指定目标,const表示一个变量或一个变量的存储单元保持不变。因此,在代码中加入关键字const,可以去除指令间的相关性。例如下面的程序:

void vecsum(short *sum,short*in1,short*in2,unsigned int N)

{

int i;

for(i=0;isum=in1+in2;

}      由其相关图2(a)可见,写sum可能对指针in1、in2所指向的地址有影响,从而in1和in2的读操作必须等到写sum操作完成之后才能进行,降低了流水效率,为帮助编译器确定存储器的相关性,使用const关键字来指定一个目标,上面的源程序可改为含关键字const的优化源代码:

void vecsum(short * sum, const short*in1,const short*in2,unsigned int N)

{

int i;

for(i=0;isum=in1+in2;

}

由其相关图2(b)可见,由于使用了关键字const,消除了指令之间的相关路径,从而使编译器能够判别内存操作之间的相关性,找到更好的指令执行方案。

3) 使用内联函数(intrinsics)      内联函数是C64X编译器提供的专门函数,它们与嵌入式的汇编指令是一一对应的,其目的是快速优化C源程序。在源程序中调用内联函数,与调用一般的函数相同,只不过内联函数名称前有下划线作特殊标识。当汇编指令功能不易采用C语言表达时,可采用内联函数表示。例如在定点运算中经常要求出源操作数的冗余符号位数,这一功能如果用C完成的话,需要如下的代码:

unsigned int norm(int src1)

{

unsigned int sign, result = 0;

sign = src1 & 0x80000000;

while(1)

{

if(sign)

{

if((src1 = src1 << 1) & sign)

result += 1;

else

return result;

}

else

{

if((src1 = src1 << 1) | sign)

return result;

else

result += 1;

}

}

}

该源程序代码冗长,有较多的逻辑操作和判断跳转,运行效率低下。若用内联函数,则是result =_norm(src1),减少了代码长度,提高了运行效率。因此对于需要大量C代码才能表示的复杂功能,应该尽量用C64X的内联函数来表示。

4) short型数据的int处理

C64XDSP具有双16bit扩充功能,芯片能在一个周期内完成双16bit的乘法、加减法、比较、移位等操作。在设计时,当对连续的short型数据流操作时,应该转化成对int型数据流的操作,这样一次可以把两个16位的数据读入一个32位的寄存器,然后用内部函数来对它们处理(如_sub2等),充分运用双16bit扩充功能,一次可以进行两个16bit数据的运算,速度将提升一倍。

5) 尽量少进行函数调用

函数调用的时候,要将PC和一些寄存器压栈保存,函数返回时,则将这些寄存器出栈返回,增加了一些不必要的操作。所以一些小的函数,最好是用适当的内联函数代替直接写入主函数里,一些调用不多的函数,也可以直接写入主函数内,这样可减少不必要的操作,提高速度。但是这样往往会增加程序的长度,因此是一种利用空间换取时间的办法。

6) 尽量使用逻辑运算代替乘除运算

在DSP里,乘除运算指令的执行时间要远远超过逻辑移位指令,尤其是除法指令,在设计的时候,可以根据实际情况,进行一些调整,尽量用逻辑移位运算来代替乘除运算,这样可以加快指令的运行时间。

7) 软件流水线技术的使用

软件流水线技术用来对一个循环结构的指令进行调度安排,使之成为多重迭代循环并行执行。在编译代码时,可以选择编译器的-o2或-o3选项,则编译器将根据程序尽可能地安排软件流水线。

在DSP算法中存在大量的循环操作,因此充分地运用软件流水线方式,能极大地提高程序的运行速度。但使用软件流水线还有下面几点限制:

● 循环结构不能包含代码调用,但可以包含内联函数。

● 循环计数器应该是递减的。

● 循环结构不能包含break,if语句不能嵌套,条件代码应当尽量的简单。

● 循环结构中不要包含改变循环计数器的代码。

● 循环体代码不能过长,因为寄存器(32个)的数量有限,应该分解为多个循环。

在软件流水线的运用上,应该尽量使复杂的循环分解成简单的小循环,以避免寄存器的数量不够;对于过于简单的循环,应该适当的展开,以增加代码数量,增加流水线中的迭代指令。

8) 采用指令乱序技术

程序中,有些指令的执行顺序没有严格的要求,可以作出一些位置上的调整,因此可以适当的调整这些指令的位置,穿插于其他的指令之中,从而减小指令的相关性,增加运行时的并行性。

尤其在循环里,当循环体较小的时候,可以把多个循环的代码写在一个循环体里,合并成一个循环,从而减小循环内指令的相关性,增加指令运行的并行性。但是要注意不要使循环过于复杂,以至不能进行软件流水线的优化。

由于C语言编译出来的程序,不是最有效率的汇编语言,而没有办法达到实时播放。所以为了要使程序执行的速度能够加快,必须要做最佳化,使其能够达到实时播放的速度。然而C6x 的编译器也提供了最佳化的指令,如在编译时加上 -o3 的参数,它可以用软件来分析我们的程序是否有可以改进的地方,如此一来,在产生组语的汇编语言档案之前,编译器会对我们写的C语言程序不断的进行编译,也会对程序中的循环部份重新编排,产生另一较有效率的核心循环,以最有效率的方式重新编排程序,来加快程序速度:

方法一  把浮点运算改成定点运算

因为C6x DSP板并不支持浮点运算,但我们的原始程序代码是浮点运算的格式,所以必须改成定点运算,而其修改后的执行速度也会加快很多。我们采用 Q-format 规格来表示浮点运算。以下将介绍其相关原理。

定点DSP使用固定的小数点来表示小数部份的数字,这也造成了使用上的限制,而为了要分类不同范围的小数点,我们必须使用Q-format的格式。不同的Q-format表示不同的小数点位置,也就是整数的范围。表2呈现Q15数字的格式,要注意在小数点后的每一位,表示下一位为前一位的二分之一,而MSB (most-significant-bit ) 则被指定成有号数 ( Sign bit )。由表2可以知道,当有号数被设成0而其余位设成1时,可得到最大的正数 (7FFFH ) ;而当有号数被设成1而其余位设成0时,可得到最大的负数 ( 8000H ) 。所以Q15格式的范围从-1到0.9999694 (@1) ,因此我们可以藉由把小数点向右移位,来增加整数部份的范围,如表3所示,Q14格式的范围增为-2.0到1.9999694 (@2) ,然而范围的增加却牺牲了精确度。

方法二  建立表格 ( table )

原来程序的设计是除了要读AAC的档案外,在译码时,还要再另外读取一些C语言程序代码的内容再做计算,如读取一些数值做sin、cos、exp的运算,但是为了加快程序的执行速度,故将这这些运算的结果建成表格,内建在程序中,可以不必再做额外的计算动做,以加速程序。

方法三  减短程序的长度

1.去除Debug的功能

原本程序在Debug的阶段时,就加了许多用来侦测错误的部份,程序 Debug完后,已经没有错误发生,所以就可以把这些部份给去除,以减少程序的长度,也可以减少程序执行时的时脉数,加快程序的速度。

2.去除计算时脉 ( clock ) 功能

原本程序可以计算执行程序所需的时脉数,我们也可以把这些部份给去除,如果有需要计算时脉时,我们可以用C6x的工具软件来作,功能更强大。

方法四  减少I/O 过程

原本在做译码的动作时,是先读取AAC档案的一部份做译码,译码完成后再读取下一部份,再做译码。但是由于C6x的板子跟PC做档案读取时相当的缓慢,读取的动作占了大部份的时间,所以就将程序改成先将AAC档案全部读到C6x的内存中,再做译码。或是将AAC建成表格(约1 MB),以避免DSP板上的内存不足.

方法五  减少子程序的呼叫

在呼叫子程序时,必须先将缓存器的内容放到堆栈 (stack) 中,而从子程序返回时,也要将这些缓存器原本的内容从堆栈中取出来。但是有些子程序的长度很短,而且被呼叫的次数又很多,往往几个时脉就可以完成却浪费时间在存取堆栈的内容上,所以干脆将这些很短的子程序直接写在主程序当中,以减少时脉数.

方法六  写汇编语言

虽然由C语言所编译出来的汇编语言可以正确无误的执行,但是这个汇编语言却不是最有效率的写法,所以为了增加程序的效率,于是在某些地方,例如一些被呼叫很多次且程序代码不长的函式(function),必须改以自己动手写汇编语言来取代。

方法七  利用平行处理的观念

C6x是一颗功能强大的处理器,它CPU的内部提供了八个可以执行不同指令的单元,也就是说最多可以同时处理八个指令。所以如果我们可以用它来作平行处理,我们就可以大大的缩短程序执行的时间,最有效率的来利用它来作解碼的动作。

最后还要知道:

第三级优化(-O3),效率不高(经验),还有一些诸如用一条读32位的指令读两个相邻的16位数据等,具体情况可以看看C优化手册。 但这些效率都不高(虽然ti的宣传说能达到80%,我自己做的时候发现绝对没有这个效率!65%还差不多),如果要提高效率只能用汇编来做了。还有要看看你的c程序是怎么编的,如果里面有很多中断的话,6000可以说没什么优势。还有,profiler的数据也是不准确的,比实际的要大,大多少不好说。还有dsp在初始化的时候特别慢,这些时间就不要和pc机相比了,如果要比就比核心的部分。

关于profile:

C6x的Debug工具提供了一个profile界面。在图9中,包括了几个重要的窗口,左上角的窗口是显示出我们写的C语言,可以让我们知道现在做到了哪一步。右上角的窗口显示的是C6x所编译出来的汇编语言,同样的我们也可以知道现在做到了哪一步。左下角的窗口是命令列,是让我们下指令以及显示讯息的窗口。而中间的profile窗口就是在profile模式下最重要的窗口,它显示出的项目如下表:

表5:profile的各项参数[8]

字段            意义

Count         被呼叫的次数

Inclusive     包含子程序的总执行clock数

Incl-Max    包含子程序的执行一次最大clock数

Exclusive   不包含子程序的总执行clock数

Excl-Max    不包含子程序的执行一次最大clock数

利用这个profile模式我们可以用来分析程序中每个函数被呼叫的次数、执行的时脉数等等。用这个分析的结果,我们就可以知道哪个函数所花费的时脉最多,是可以再改进的,而针对它来作最佳化。

汇编代码级的优化

在经过C代码的优化之后,还不能满足性能上的要求,则可以通过profile

clock工具找出效率很低的部分,使用线性汇编重新改写。再通过汇编优化器编译,汇编优化器从输入的线性汇编代码中,完成以下功能:

● 寻找可以平行执行的CPU指令。

● 在软件流水线期间,处理流水线标号。

● 分配寄存器的用法。

● 分配功能单元。

TI提供的汇编优化器可以得到很高的效率,一般可以满足性能上的要求。

优化中的问题:

在优化过程中,总是要对程序进行一定的改动,这样经常会出现一些问题。

1) 优化结果的验证

优化过的程序往往不知道是否运行正确,这就需要加以验证。一般采用的办法就是通过测试序列来验证。测试序列指的是对于不同的算法所取的一组特殊的数据,这些数据可以准确的反映算法的特性。测试序列中每组数据包括输入数据和输出数据,通过对输入数据的运算,把结果与输出数据进行比较,判断程序的正确性。一些常见的算法,一般都提供了测试序列。还有一些,没有测试序列。这时就需要根据算法的特点,自己构造测试序列,进行验证。构造的时候,注意序列最好有几组,数据最好有一定的长度,这样验证的更准确。

2) 内存泄漏的问题

C64X系列DSP的内部存储空间有1MB,其中程序和数据还有CPU的二级缓存将共享这片空间,因此当程序的运行不正常时,很有可能就是内存泄漏造成的。因此,在程序设计中,应尽量不用指针,同时注意进行边界检测。

程序设计的一些方法

程序设计时,一切以满足实际的要求为目标。在实际的设计中,除了优化能够提高性能以外,还可以采取其他的办法,利用DSP的特性,提高程序的运行性能,满足实际的设计要求。

1) 把程序和经常要用的数据放入片内RAM

片内RAM与CPU

工作在同一时钟频率,比片外RAM性能高得多。因此把程序放在片内可以大大提高运行的速度。同时对于一些经常要用到的数据,放入片内,也会节省处理时间。

2) 通过DMA技术搬移数据

对于C64X芯片,其片内RAM有1MB,但是对于一些大型的图像处理算法而言,仍可能是不够的,因此经常通过DMA技术,把需要用到的数据搬入片内,把不需要的搬到片外,可以大大的提高程序的运行速度。

3) CACHE的使用

增大CACHE,可以明显的提高性能。但是C64X系列DSP中程序和数据还有CACHE共享片内RAM,因此增大CACHE,就减小了实际的片内可用空间,设计中需要注意。

全文完

C语言lo如何优化运行界面,高质量程序优化总结整理【经典】相关推荐

  1. C语言游戏: 俄罗斯方块(Tetris)@兼谈程序优化方法 [源码+exe下载]

    消除重复:如何将程序逻辑与数据分开? ----俄罗斯方块(Tetris)@兼谈程序优化方法 背景提示: 1,数据,是程序设计的根本.因为任何程序都可以看作是一组数据,和作用于其上的一组操作,这也是面向 ...

  2. 《Python编程实战:运用设计模式、并发和程序库创建高质量程序》—— 第1章 Python的创建型设计模式...

    本节书摘来自华章出版社<Python编程实战:运用设计模式.并发和程序库创建高质量程序>一 书中的第1章,第1.1节,作者:(美) Mark Summerfield,更多章节内容可以访问云 ...

  3. 高质量程序员求职指南

    ✅简历模板随心选 ✅面试刷题不能停 ✅大厂面经助你赢 指南在手,offer我有 拿好这份高质量程序员求职指南,赢在2022春招起跑线! ❓"金三银四",消失了吗? 冬寒还未完全散去 ...

  4. 【C语言快速入门】三万字+高质量教学

    写在前面: 简单介绍一下本篇文章的主要目的: 是让新手玩家快速认识并了解C语言基础内容和语法结构,并没有深入去探究,让大家对C语言有个大概且全面的认识. 相信我,这篇文章虽然很长,但不会让你从入门到入 ...

  5. C语言程序设计教程的读后感,《高质量c语言编程》读后感

    <高质量c语言编程>读后感 当认真看完一本名著后,大家一定对生活有了新的感悟和看法,现在就让我们写一篇走心的读后感吧.那么如何写读后感才能更有感染力呢?以下是小编收集整理的<高质量c ...

  6. [FFMpeg开发]视频转高质量GIF优化方案(接近ps生成效果),从原理剖析

    摘要 虽然此前有人发过了,但是这个博主没有分析原理并且没有提炼出来.不适合开发者学习. 所以我只是进行二次优化,原文高质量视频转gif 此前,做产品的时候,产品用到了ffmpeg框架,手上几个ffmp ...

  7. 《Python编程实战:运用设计模式、并发和程序库创建高质量程序》—— 导读

    前 言 本书面向有志于拓展及深化Python知识的读者,它将教你如何改进Python程序的质量.可靠性.速度.可维护性以及可用性.书中包含大量实用的范例与思路,可帮助大家提升Python编程水平. 本 ...

  8. 有哪些高质量程序员聚集地论坛分享?

    不废话,直接上! 一.技术提升 GitHub 程序员托管代码的平台,很多开发者都会在上面找各种各样的开源项目来学习.阿里.腾讯.字节跳动.美团.Google.Micosoft等国内外大厂都有自己的Gi ...

  9. 推荐两个高质量程序猿国外接单网站—自由开发工作者

    因为我是程序员出身,所以身边的朋友有时候有需求会找我做,一般给个项目估价和时间评估, 然后达成合作就开干了.最近也有一些朋友在问有没有什么好一点的接单网站,这边博主将两个高质量的国外接单的网站推荐一下 ...

  10. oracle书写高质量sql,干货!SQL性能优化,书写高质量SQL语句

    写SQL语句的时候我们往往关注的是SQL的执行结果,但是是否真的关注了SQL的执行效率,是否注意了SQL的写法规范? 以下的干货分享是在实际开发过程中总结的,希望对大家有所帮助! 1. limit分页 ...

最新文章

  1. 小米note3无线显示电脑连接服务器,小米note3如何连接电脑 小米note3连接电脑没反应怎么办...
  2. 速卖通关键词挖掘工具_网站优化必备的关键词挖掘工具
  3. 解决修改“文件夹选项”后仍不能显示隐藏文件一例
  4. 【Node】node启动过程
  5. getparameter方法中文显示问号解决方法_电脑显示器花屏怎么办 电脑显示器花屏解决方法【原因分析】...
  6. jQuery编写widget的一些窍门
  7. mysql 慢日志报警_一则MySQL慢日志监控误报的问题分析
  8. 销售管理系统 java_用Java从零写一个B2C商城,看完不要再说自己没有实战经验了!...
  9. Tensorflow 之 name/variable_scope 变量管理
  10. 抢鲜体验:openGauss 安装编译过程要点及问题解决
  11. 2018.09.18 循环终止
  12. 精选36道SQL练习题解析 from(原50道SQL练习题)
  13. 1.运动学分析-正运动学
  14. dbscan聚类python_DBSCAN聚类算法Python实现
  15. 西班牙计算机专业排名,西班牙大学及专业排名
  16. Linux系统有哪些?盘点常用的 8 个Linux系统!
  17. AAAI最佳论文Informer 解读
  18. 如何批量修改图片名称?
  19. DOS系统和windows系统有什么区别
  20. ios不行安卓可以 微信签名_微信支付-支付验证签名失败(iOS)

热门文章

  1. 腾讯/网易/263/阿里云企业邮箱登录入口
  2. python tkinter ttk_关于tkinter和ttk的新教程,适用于Python 3
  3. 物联网智能家居与射频识别技术应用
  4. 微信小程序InnerAudioContext IOS真机无法播放声音
  5. 职场工作人员需不需要写日报
  6. 5G NR — 基站(Base Station)
  7. 万达商管再次递表港交所:上半年净利润40亿元,外部股东阵容强大
  8. JAVA POI 对excel加密后 无法打开的解决办法
  9. 武汉大学计算机 韩立,文澜学术系列讲座 第135期 武汉大学经济与管理学院韩立宁老师:“Financial Network and Industry Connectedness”...
  10. 麻雀优化算法SSA及其改进策略