DSP_TMS320F28377D_算法加速方法4_C语言编程优化

前面3篇的优化思路是从硬件本身和函数库这些方向去加速, 本文则仅从代码本身的效率去考虑加速的方法。

1、用全局变量比用局部变量快

void testfunction1(){  // 局部变量int i;double s,a,b;a = 1.023;b = 12.23;for(i = 0; i < 1000; i++){s = __divf32(a,b);}
}int i1;
double s1,a1,b1;
void testfunction2(){   // 全局变量a1 = 1.023;b1 = 12.23;for(i1 = 0; i1 < 1000; i1++){s1 = __divf32(a1,b1);}
}

2、用指针增量操作代替数组下标寻址

double a[10] = {0.1,0.2,0.3,0.4,0.5,0.1,0.2,0.3,0.4,0.5};
double *p = a;
void testfunction1(){  // 数组下标int i,j;double s;for(i = 0; i < 1000; i++){for(j = 0; j < 10; j++){s = __sqrt(a[j]);}}
}void testfunction2(){   // 指针增量int i,j;double s;for(i = 0; i < 1000; i++){p = a;for(j = 0; j < 10; j++){s = __sqrt(*p++);}}
}

 3、尽量少用函数,用宏函数或者直接实现来替代函数

double a = 1.0;
double b = 2.0;
double c = 3.0;
double d = 4.0;
double e = 0;#define TEST(a,b,c,d) (__divf32((__sqrt(a*b)+c),d))double testfun(double a, double b,double c, double d){return __divf32((__sqrt(a*b)+c),d);
}

注:直接实现和用宏定义的函数应该时间是一样或者说是很接近的,没有优劣之分。 18001900的差别应该是测试方法有些不可控因素导致的。如果把直接实现的代码放在第三个部分,它也1800us。
 

4 多重循环长循环放在层,短循环放在

在系统的多重循环过程中,需要程序员将最长的循环内容设置在系统的最内层,同时需要将最短的循环内容设置在系统的最外层。这样,能够有效提升CPU的运行效率,促进CPU的跨切循环次数。

5 从算法本身的复杂度去优化

假设我要计算 1+2+…+100

6 整数的乘除用位移运算替代

DSP的测试结果来看,位移运算和乘法时间一模一样,根本没区别。不推荐使用。

7 通信优化

DSP经常会用到串口通信,串口发送主要优化思路是去掉多余的赋值语句循环语句。

float fDrivex = 0.15;
float fDrivey = -0.3;
Uint16 FSM_TxBuffer[9]={0,0,0,0,0,0,0,0,0};struct _FSM_com_struct_
{Uint16  sHeader;Uint16  controlmode;int     iEddyx;int     iEddyy;Uint16  Check;Uint16  tail;
}FSM_Tx_struct;
void testfunction(){ // 优化前int i = 0;FSM_Tx_struct.iEddyx = (int16)(fDrivex * 21333.33);FSM_Tx_struct.iEddyy = (int16)(fDrivey * 21333.33);FSM_TxBuffer[0] = 0x55;FSM_TxBuffer[1] = 0xAA;FSM_TxBuffer[2] = 0x10;FSM_TxBuffer[8] = 0xCC;FSM_TxBuffer[3] = ( (Uint16)(FSM_Tx_struct.iEddyx) >> 8);FSM_TxBuffer[4] = ( (Uint16)(FSM_Tx_struct.iEddyx) & 0x00FF);FSM_TxBuffer[5] = ( (Uint16)(FSM_Tx_struct.iEddyy) >> 8);FSM_TxBuffer[6] = ( (Uint16)(FSM_Tx_struct.iEddyy) & 0x00FF);FSM_TxBuffer[7] = 0xFF ^ FSM_TxBuffer[2] ^ FSM_TxBuffer[3] ^ FSM_TxBuffer[4] ^ FSM_TxBuffer[5] ^ FSM_TxBuffer[6];for(i = 0; i < 9; i++){ScicRegs.SCITXBUF.all   = FSM_TxBuffer[i];while (ScicRegs.SCICTL2.bit.TXRDY == 0);}}
float fDrivex = 0.15;
float fDrivey = -0.3;
Uint16 FSM_TxBuffer[9]={0,0,0,0,0,0,0,0,0};struct _SCI_TX_struct_
{int     iEddyx;int     iEddyy;
};struct _TxBUF_struct_
{Uint16  Low:8;Uint16  High:8;
};union sciTxunion {struct  _TxBUF_struct_  TxBUF[2];struct  _SCI_TX_struct_ bit;
} FSM_Tx_union;void testfunction1(){ // 优化后FSM_Tx_union.bit.iEddyx = (int16)(fDrivex * 21333.33);FSM_Tx_union.bit.iEddyy = (int16)(fDrivey * 21333.33);ScicRegs.SCITXBUF.all   = 0x55;while (ScicRegs.SCICTL2.bit.TXRDY == 0);ScicRegs.SCITXBUF.all   = 0xAA;while (ScicRegs.SCICTL2.bit.TXRDY == 0);ScicRegs.SCITXBUF.all   = 0x10;while (ScicRegs.SCICTL2.bit.TXRDY == 0);ScicRegs.SCITXBUF.all   = FSM_Tx_union.TxBUF[0].High;while (ScicRegs.SCICTL2.bit.TXRDY == 0);ScicRegs.SCITXBUF.all   = FSM_Tx_union.TxBUF[0].Low;while (ScicRegs.SCICTL2.bit.TXRDY == 0);ScicRegs.SCITXBUF.all   = FSM_Tx_union.TxBUF[1].High;while (ScicRegs.SCICTL2.bit.TXRDY == 0);ScicRegs.SCITXBUF.all   = FSM_Tx_union.TxBUF[1].Low;while (ScicRegs.SCICTL2.bit.TXRDY == 0);ScicRegs.SCITXBUF.all   = 0xEF ^ FSM_Tx_union.TxBUF[0].High ^ FSM_Tx_union.TxBUF[0].Low ^ FSM_Tx_union.TxBUF[1].High ^ FSM_Tx_union.TxBUF[1].Low;while (ScicRegs.SCICTL2.bit.TXRDY == 0);ScicRegs.SCITXBUF.all   = 0xCC;while (ScicRegs.SCICTL2.bit.TXRDY == 0);}

串口接收主要优化思路也是去掉多余的赋值语句,另外,去掉多余的逻辑判断

// 优化前
interrupt void getScic(void){int i = 0;FSMRxCheck = 0xFF;for(i = 0; i < 9; i++){FSM_RxBuffer[i]         = ScicRegs.SCIRXBUF.all;if(i > 1 && i<7){FSMRxCheck ^= FSM_RxBuffer[i];}}FSMRxCheck = FSMRxCheck & 0x00FF;FSM_Rx_Cnt  = FSM_Rx_Cnt + 1;ScicRegs.SCIFFRX.bit.RXFIFORESET    = 0;    // 0: Write 0 to reset the FIFO pointer to zero, and hold in reset.ScicRegs.SCIFFRX.bit.RXFIFORESET    = 1;    // 1: Re-enable receive FIFO operationScicRegs.SCIFFRX.bit.RXFFINTCLR     = 1;    // 1: Write 1 to clear RXFFINT flag in bit 7PieCtrlRegs.PIEACK.all  = PIEACK_GROUP8;    // Writing a 1 to the respective interrupt bit clears the bit and enables the PIE block to drive a pulse into// the CPU interrupt input if an interrupt is pending for that group.
}void getEddy(void){FSM_Rx_struct.sHeader       =   ( FSM_RxBuffer[0] << 8 ) + FSM_RxBuffer[1];FSM_Rx_struct.controlmode   =   FSM_RxBuffer[2];FSM_Rx_struct.iEddyx        =   (int)( ( FSM_RxBuffer[3] << 8) +  FSM_RxBuffer[4] );FSM_Rx_struct.iEddyy        =   (int)( ( FSM_RxBuffer[5] << 8) +  FSM_RxBuffer[6] );FSM_Rx_struct.Check         =   FSM_RxBuffer[7];FSM_Rx_struct.tail          =   FSM_RxBuffer[8];if(FSM_Rx_struct.sHeader == 0x55AA && FSM_Rx_struct.tail == 0xCC && FSMRxCheck == FSM_Rx_struct.Check){fEddyx  = (float)FSM_Rx_struct.iEddyx * 0.000046875;fEddyy  = (float)FSM_Rx_struct.iEddyy * 0.000046875;//asm ("      ESTOP0");}}
// 优化后
Uint16 FSMRxCheck = 0x00FF;
interrupt void getScic(void){int i = 0;for(i = 0; i < 9; i++){FSM_RxBuffer[i]         = ScicRegs.SCIRXBUF.all;if(i > 1 && i<7){FSMRxCheck ^= FSM_RxBuffer[i];}}DecodeEn = 1;ScicRegs.SCIFFRX.bit.RXFIFORESET    = 0;    // 0: Write 0 to reset the FIFO pointer to zero, and hold in reset.ScicRegs.SCIFFRX.bit.RXFIFORESET    = 1;    // 1: Re-enable receive FIFO operationScicRegs.SCIFFRX.bit.RXFFINTCLR     = 1;    // 1: Write 1 to clear RXFFINT flag in bit 7PieCtrlRegs.PIEACK.all  = PIEACK_GROUP8;    // Writing a 1 to the respective interrupt bit clears the bit and enables the PIE block to drive a pulse into// the CPU interrupt input if an interrupt is pending for that group.
}void getEddy(void){if( FSMRxCheck==FSM_RxBuffer[7] ){fEddyx  = (float)( (FSM_RxBuffer[3]<<8) + FSM_RxBuffer[4] ) * 0.000046875;fEddyy  = (float)( (FSM_RxBuffer[5]<<8) + FSM_RxBuffer[6] ) * 0.000046875;FSMRxCheck  = 0x00FF;}}

 

 

 后续暂时是不会再写DSP算法加速的方法了。 感谢您的阅读,如果您还有什么优化的方法和思路,欢迎留言分享、收藏点赞

 

 

 

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/98217.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

TypeScript_线性结构-数组-栈结结构

数据结构与算法 面试经典 150 题 编程的最终目的只有一个&#xff1a;对数据进行操作和处理 术之尽头炁体源流编程尽头数据结构 数据结构与算法的本质就是一门专门研究数据如何组织、存储和操作的科目 系统、语言、框架源码随处可见数据结构与算法 无论是操作系统&#xff…

手写Mybatis:第13章-通过注解配置执行SQL语句

文章目录 一、目标&#xff1a;注解配置执行SQL二、设计&#xff1a;注解配置执行SQL三、实现&#xff1a;注解配置执行SQL3.1 工程结构3.2 注解配置执行SQL类图3.3 脚本语言驱动器3.3.1 脚本语言驱动器接口3.3.2 XML语言驱动器 3.4 注解配置构建器3.4.1 定义增删改查注解3.4.2…

Go实现LogCollect:海量日志收集系统【上篇——LogAgent实现】

Go实现LogCollect&#xff1a;海量日志收集系统【上篇——LogAgent实现】 下篇&#xff1a;Go实现LogCollect&#xff1a;海量日志收集系统【下篇——开发LogTransfer】 项目架构图&#xff1a; 0 项目背景与方案选择 背景 当公司发展的越来越大&#xff0c;业务越来越复杂…

Mybatis学习|Mybatis缓存:一级缓存、二级缓存

Mybatis缓存 MyBatis包含一个非常强大的查询缓存特性&#xff0c;它可以非常方便地定制和配置缓存。缓存可以极大的提升查询效率。 MyBatis系统中默认定义了两级缓存:一级缓存和二级缓存 默认情况下&#xff0c;只有一级缓存开启。(SqlSession级别的缓存&#xff0c;也称为本地…

FANUC机器人电气控制柜内部硬件电路和模块详细介绍

FANUC机器人电气控制柜内部硬件电路和模块详细介绍 PSU电源单元 通过背板传输了如下电源 +5 +2.0V +3.3 +24v +24E +15V -15V 主板--接口描述: 主板内部结构: 面板电路板: 引申一下 KM21 与 KM22 的作用它们分别接至操作面板上上的急停按

入门力扣自学笔记277 C++ (题目编号:42)(动态规划)

42. 接雨水 题目&#xff1a; 给定 n 个非负整数表示每个宽度为 1 的柱子的高度图&#xff0c;计算按此排列的柱子&#xff0c;下雨之后能接多少雨水。 示例 1&#xff1a; 输入&#xff1a;height [0,1,0,2,1,0,1,3,2,1,2,1] 输出&#xff1a;6 解释&#xff1a;上面是由数组…

Vue3---uni-app--高德地图引用BUG

先给报错信息&#xff1a;module libs/map//libs/map_min.js is not defined, require args is /libs/map_min.js 查看我引用方法&#xff1a; 本人查阅资料发现 是 require 使用的是 commonJS方式引用说这个适配Vue2可我项目是Vue3应该使用ES6语法糖 然后我有跑了项目发现BU…

CCKS2023:基于企业数仓和大语言模型构建面向场景的智能应用

8月24日-27日&#xff0c;第十七届全国知识图谱与语义计算大会&#xff08;CCKS 2023&#xff09;在沈阳召开。大会以“知识图谱赋能通用AI”为主题&#xff0c;探讨知识图谱对通用AI技术的支撑能力&#xff0c;探索知识图谱在跨平台、跨领域等AI任务中的作用和应用途径。 作为…

VScode SSH无法免密登录

配置方法 引用高赞贴&#xff1a;点击 debug方法 连不上需要找到问题原因&#xff0c;看ssh的 log Linux服务器&#xff1a;2222是我们指定的端口&#xff0c;可以是1234等 sudo /usr/sbin/sshd -d -p 2222windows这边&#xff1a;端口号要一致 ssh -vvv ubuntusername192…

《Python魔法大冒险》005 魔法挑战:自我介绍机器人

魔法师和小鱼坐在图书馆的一扇窗户旁&#xff0c;窗外的星空闪烁着神秘的光芒。魔法师轻轻地拍了拍小鱼的肩膀。 魔法师&#xff1a; 小鱼&#xff0c;你已经学会了编写简单的魔法程序&#xff0c;现在我要教你如何创造一个有自己思想的机器人&#xff0c;让它能够和我们一样&…

css 文字单行多行超出长度后显示 ...

0.超出… 1、单行文本超出 <div class"content">测试数据&#xff1a;css单行文本超出显示省略号--------</div><style> .content{width: 200px;height: 200px;overflow:hidden;white-space: nowrap;text-overflow: ellipsis;-o-text-overflow:el…

电梯SIP-IP五方对讲管理系统

电梯SIP-IP五方对讲管理系统 是深圳锐科达精心打磨的一款IP数字信号对讲设备&#xff0c;是在传统电梯对讲系统基础上的一次全新升级&#xff0c;突破了模拟、FM调频系统存在的技术障碍&#xff0c;实现联网;在模/数交替的过程中&#xff0c;继承了模拟、FM调频系统的优点&…