2014年8月7日,看了一片很长见识的博文,关于DSP如何优化的,有一个问题没有搞通,“百度”一下关键字,居然搜查了一模一样的博文N片,现在也搞不懂这篇博文的原创作者是谁了。反正我感觉直接转摘过去,要是消化不掉,也没啥意思,所以我把我可以理解消化的就先记录下来吧。

一、双重循环或多重循环在保证功能的前提下,减少嵌套循环的层数,原因有二个,如下:

1)优化器优化时只在最内层循环中形成一个 pipeline,这样循环语句就不能充分利用C6 的软件流水线,而且对于内部循环的次数较少的情况,消耗在 prolog(填充)和eplog(排空)上的 cycle 数也是不可忽视的。

2) 一个 cycle 内使用两个乘法器,如果内层循环循环次数较少,运算量也不大,一个cycle 只使用一次乘法器,而事实上我们可以在,所以还可以充分利用另外的一个乘法器。
    备注:一个内层循环会形成一个pipeline,流水优化是在pipeline中,一个pipeline中代码运行的时间,会消耗一个或者多个cycle。

例子:FIR滤波器原始程序
  void fir2(const short input[], const short coefs[], short out[])
  {
  int i, j;
  int sum = 0;
  for (i = 0; i < 40; i++)
  {
    for (j = 0; j < 16; j++)
      sum += coefs[j] * input[i + 15 - j];
    out[i] = (sum >> 15);
  }

可以优化为:
 void fir2_u(const short input[], const short coefs[], short out[])
  {
  int i, j;
  int sum;
   for (i = 0; i < 40; i++)
   {
    sum = coefs[0] * input[i + 15];
     sum += coefs[1] * input[i + 14];
     sum += coefs[2] * input[i + 13];
     sum += coefs[3] * input[i + 12];
     sum += coefs[4] * input[i + 11];
     sum += coefs[5] * input[i + 10];
     sum += coefs[6] * input[i + 9];
     sum += coefs[7] * input[i + 8];
     sum += coefs[8] * input[i + 7];
     sum += coefs[9] * input[i + 6];
     sum += coefs[10] * input[i + 5];
     sum += coefs[11] * input[i + 4];
     sum += coefs[12] * input[i + 3];
     sum += coefs[13] * input[i + 2];
     sum += coefs[14] * input[i + 1];
     sum += coefs[15] * input[i + 0];
     out[i] = (sum >> 15);
   }

}

二、使用intrinsic函数,将16位扩展为32位
c6000编译器提供的intrinsic 可快速优化C代码,intrinsic用前下划线表示同调用函数一样可以调用它,即直接内联为C6000的函数。
例如,“aReg_ll = (Word40)_mpyu(L_var1, L_var2)>>16”中“_mpyu”就是一个intrinsics函数,它表示两个无符号数的高16位相乘,结果返回。

这些内联函数定义在CCS所在的C6000/CGTOOLS/Include目录下的C6X.h文件中。
下面这个例子是C6000的“Programmer's Guide”上提取的使用intrinsics优化C代码的例子。
源代码:
int dotprod(const short *a, const short *b, unsigned int N)
{
int i, sum = 0;
for (i = 0; i < N; i++)
sum += *(a+i) * *(b+i);
return sum;
}

改编后代码:
int dotprod(const int *a, const int *b, unsigned int N)
{
int i, sum1 = 0, sum2 = 0;
for (i = 0; i < (N >> 1); i++)
{
sum1 += _mpy (*(a+i), *(a+i));
sum2 += _mpyh(*(a+i), *(a+i));
}
return sum1 + sum2;
}

三、使用 const 可以限定目标

C6000编译器如果确定两条指令是不相关的,则安排它们并行执行。 关键字const可以指定一个变量或者一个变量的存储单元保持不变。
这有助于帮助编译器确定指令的不相关性。例如下例中,源代码不能并行执行,而结果改编后的代码可以并行执行。
void fir_fxd1(short input[], short coefs[], short out[])
{
int i, j;
for (i = 0; i < 40; i++)
{
for (j = 0; j < 16; j++)
out[i*16+j]= coefs[j] * input[i + 15 - j];
}
}
改编后的代码:
void fir_fxd2(const short input[], const short coefs[], short out[])
{
int i, j;
for (i = 0; i < 40; i++)
{
for (j = 0; j < 16; j++)
out[i*16+j]= coefs[j] * input[i + 15 - j];
}

}

四、if...else...语句的优化

如果在循环中出现if...else...语句,由于if...else...语句中有跳转指令,而每个跳转指令有5个延迟间隙,因此程序执行时间延长;另外,循环内跳转也使软件流水受到阻塞。直接使用逻辑判断语句可以去除不必要的跳转。
源代码:
if (sub (ltpg, LTP_GAIN_THR1) <= 0)
{
adapt = 0; 
}
else

if (sub (ltpg, LTP_GAIN_THR2) <= 0)
{
adapt = 1; 
}
else
{
adapt = 2; 
}
}

改编后的代码:
  adapt = (ltpg>LTP_GAIN_THR1) + (ltpg>LTP_GAIN_THR2);

本篇先写到这里,以上内容均属于个人理解,事例和文字来源网络,若有新的理解,将持续更新。

C6000代码层面优化(一)的更多相关文章

  1. Java开发代码性能优化总结

    代码优化,可能说起来一些人觉得没用.可是我觉得应该平时开发过程中,就尽量要求自己,养成良好习惯,一个个小的优化点,积攒起来绝对是有大幅度效率提升的.好了,将平时看到用到总结的分享给大家. 代码优化的目 ...

  2. Java开发中程序和代码性能优化

    现在计算机的处理性能越来越好,加上JDK升级对一些代码的优化,在代码层针对一些细节进行调整可能看不到性能的明显提升, 但是我觉得在开发中注意这些,更多的是可以保持一种性能优先的意识,对一些敲代码时间比 ...

  3. 通过从代码层面分析Linux内核启动来探知操作系统的启动过程

    通过从代码层面分析Linux内核启动来探知操作系统的启动过程 前言说明 本篇为网易云课堂Linux内核分析课程的第三周作业,我将围绕Linux 3.18的内核中的start_kernel到init进程 ...

  4. Python 代码性能优化技巧(转)

    原文:Python 代码性能优化技巧 Python 代码优化常见技巧 代码优化能够让程序运行更快,它是在不改变程序运行结果的情况下使得程序的运行效率更高,根据 80/20 原则,实现程序的重构.优化. ...

  5. Android代码内存优化建议-OnTrimMemory优化

    原文  http://androidperformance.com/2015/07/20/Android代码内存优化建议-OnTrimMemory优化/ OnTrimMemory 回调是 Androi ...

  6. JAVA_eclipse 保留Java文件时自动格式化代码和优化Import

    Eclipse 保存Java文件时自动格式化代码和优化Import Eclipse中format代码的快捷方式是ctrl+shift+F,如果大家想保存 java文件的时候 自动就格式化代码+消除不必 ...

  7. JavaScript代码性能优化总结

    JavaScript 代码性能优化总结 尽量使用源生方法 javaScript是解释性语言,相比编译性语言执行速度要慢.浏览器已经实现的方法,就不要再去实现一遍了.另外,浏览器已经实现的方法在算法方面 ...

  8. Html代码seo优化最佳布局实例讲解

    搜索引擎对html代码是非常优化的,所以html的优化是做好推广的第一步.一个符合seo规则的代码大体如下界面所示. 1.<!–木庄网络博客–> 这个东西是些页面注释的,可以在这里加我的& ...

  9. 利用封装、继承对Java代码进行优化

    注:本文实例分别可以在oldcastle(未优化的代码)和newcastle(优化后的代码)中查看,网址见文末 城堡游戏: 城堡中有多个房间,用户通过输入north, south, east, wes ...

随机推荐

  1. OAF_开发系列22_实现OAF条形码BarCode

    20150717 Created By BaoXinjian

  2. 使用NUget发布自己的dll(转)

    一:Nuget控制台有几个常用命令 Get-Package 获取当前项目已经安装的类库 Install-Package 安装指定类库,命令格式如下:Install-Package 类库ID,示例:PM ...

  3. JS toFixed 四舍六入五成双

    以前一直以为toFixed就是四舍五入的方法,后来又有一段时间以为toFixed是五舍六入.今天终于写的时候,终于才知道toFixed是一个叫做四舍六入无成双的诡异的方法... 完全不明白为什么要这么 ...

  4. SQL2008 清除日志

    USE [master] GO ALTER DATABASE BizTest SET RECOVERY SIMPLE WITH NO_WAIT GO ALTER DATABASE BizTest SE ...

  5. 安装Nginx作为Windows服务自启动运行

    如果Nginx每次使用都需要手动启动确实很麻烦,所以最好将其设置为Windows系统服务,开机自启动就行了. 1.下载并修改运行环境支持程序 1).下载地址:http://ng-srvinst.att ...

  6. Android开发-mac上使用三星S3做真机调试

    之前一直未使用真机进行Android开发,为准备明天的培训,拿出淘汰下来的s3准备环境,竟然发现无法连接mac,度娘一番找到答案,如下:mac 系统开发android,真机调试解决方案(无数的坑之后吐 ...

  7. 欧洲宇航局(ESA)的协同设计室(CDF)

    官方网站:http://www.esa.int/SPECIALS/CDF/

  8. springmvc图片文件上传接口

    springmvc图片文件上传 用MultipartFile文件方式传输 Controller package com.controller; import java.awt.image.Buffer ...

  9. sm4加密 解密(oc)

    前几天项目用到sm4加密解密,加密为十六进制字符串,再将十六进制字符串解密.网上百度了下,sm4是密钥长度和加密明文加密密文都为16个字节十六进制数据,网上的sm4 c语言算法很容易搜到,笔者刚开始没 ...

  10. lintcode-【中等】恢复IP地址

    题目 给一个由数字组成的字符串.求出其可能恢复为的所有IP地址.链接. 样例 给出字符串 "25525511135",所有可能的IP地址为: [ "255.255.11. ...