嵌入式开发极致性能优化案例

本文转自公众号,欢迎关注
嵌入式开发极致性能优化案例
前言我们之前进行了tft刷屏测试确认了基本功能。刷屏速度是决定gui显示帧率最根本的一环,只有优化到极致的刷屏速度,才能有基础实现更好效果的gui。本篇就进行刷屏的优化,其实其思想是通用的,对于其他代码也可以参考。
1. 减少if条件判断if等条件判断会导致分支处理,一方面会增加指令,尤其是跳转指令一般执行时间比一般指令长,另外也会影响流水线和cache。
if(data&0x80) lcd_sda_set; //输出数据else lcd_sda_clr;改为串行操作
#define lcd_sda_set_val(val) lcd_ctrlb- >bsrr=val;lcd_ctrlb- >brr=val^lcd_sda2. 使用寄存器变量频繁操作的局部变量尽量使用寄存器进行缓存,避免反复从内存去加载,寄存器直接操作速度快很多。
register unsigned int data;3. 空间换时间 8次for循环改为 直接8次操作其实在memcpy等处理中也是类似操作,比如连续8次读写组合一起,再循环。以减少for判断次数,也利于内部cache流水线处理,有一些cpu还有burst处理,这也是有利的。
inline void spi_writedataf(unsigned char data){#if 0unsigned char i=0;for(i=8;i >0;i--){if(data&0x80) lcd_sda_set; //输出数据else lcd_sda_clr;lcd_scl_clr; lcd_scl_set;data< <=1;}#else//lcd_sda_lock;register unsigned int data = (data & 0x80) < < 0;lcd_sda_set_val(data);lcd_scl_clr; lcd_scl_set;data = (data & 0x40) < < 1;lcd_sda_set_val(data);lcd_scl_clr; lcd_scl_set;data = (data & 0x20) < < 2;lcd_sda_set_val(data);lcd_scl_clr; lcd_scl_set;data = (data & 0x10) < < 3;lcd_sda_set_val(data);lcd_scl_clr; lcd_scl_set;data = (data & 0x08) < < 4;lcd_sda_set_val(data);lcd_scl_clr; lcd_scl_set;data = (data & 0x04) < < 5;lcd_sda_set_val(data);lcd_scl_clr; lcd_scl_set;data = (data & 0x02) < < 6;lcd_sda_set_val(data);lcd_scl_clr; lcd_scl_set;data = (data & 0x01) < < 7;lcd_sda_set_val(data);lcd_scl_clr; lcd_scl_set;//lcd_sda_unlock;#endif}4. 使用内联函数减少函数跳转时间inline void spi_writedataf(unsigned char data)函数跳转需要时间,减少函数调用即可节约时间,尤其频繁调用的函数效果明显,但是可能增加存储空间。
5. 减少for循环嵌套 双重for嵌套改为一层forfor嵌套导致多重循环嵌套判断,浪费时间,顺序执行一般是优于分支处理的。
void lcd_clearf(unsigned int color) //刷新全屏 {unsigned int i,m;lcd_setregion(0,0,x_max_pixel-1,y_max_pixel-1);lcd_writeindex(0x2c);for(i=0;i>8); //写入高8位数据 spi_writedataf(color); //写入低8位数据 lcd_cs_set; }}6. 减少函数调用层级函数调用影响流水线,并且需要额外的上下文处理时间
lcd_clearf中直接调用spi_writedataf不再调用函数lcd_writedata_16bit
7. 使用汇编进行优化这个实际看情况建议先用其他方式进行优化,因为人工编写汇编代码不一定比编译器编写的好,除非非常熟悉汇编并且有明确的优化方向。
8. 速度测试循环刷屏使用定时器记录执行多次刷屏的时间,代码见附件。
9. 编译器速度优化选项编译器-ofast优化
执行时间分别是
660ms,782ms
我们优化后的代码快15.6%
编译器-o2优化
执行时间分别是661ms,908ms
我们优化后的代码快快27.2%
从上可以看出不管用什么编译器优化,经过上面方式人工优化后的代码都不差不多,660和661,说明编译器已经无法对我们优化后的代码再进行优化说明我们人工优化的代码不使用编译器优化也有很好的速度性能。不同的编译器优化对原来的代码影响较大-ofast执行时间从908变为了782。哪怕是采用-ofsat编译器优化,我们人工优化的代码依然还有比编译器优化的代码快15.6%,所以编译器优化无法替代人工优化。只有从设计角度去优化,避免依赖编译器优化才是根本方案。总结1.优化应该从设计上去优化而不是依赖编译器,应该先找大头,优先设计原理,算法上去优化,最后采取进行汇编等底层的优化,后者成本大效果不明显不具备可移植性等,前者成本小效果明显,不依赖于编译器。
2.建议寄存器名字和手册对应比如gpio的io锁定寄存器,头文件中是lock 手册里是lckr
2.对于io操作最好设置lock odr寄存器,这样可以指定bit直接写值而其他位不修改,而不需要if else判断分别配置brr 和bsrr,可以直接操作odr寄存器,进一步优化速度。


3DEXPERIENCE平台2023新功能揭秘!Governance云端数据管理解决方案
夏天投影机使用八大注意事项
VR近年来的发展:不是必需品却丰富我们的生活
电视和投影仪哪个更护眼,当贝X3三重权威认证
人工智能在未来空战训练中的作用是什么
嵌入式开发极致性能优化案例
压力传感器的干扰源有哪些
Skydio 研发“自主飞行”无人机 可紧跟用户进行跟拍
网络设计会因为物联网而做出改变吗
联通将推200款3G手机 携三星推互联网手机
九款先进医疗机器人:人体内部自行组装治病
具有优化功率搜索和多种安全特性的完整高效的100 mA无线充电解决方案
让我们来看看都有哪些有趣的workshop吧!
叁仟智慧物联网太阳能路灯杆有哪些优势特点?
采用UC3846实现交错并联控制
深入“万人迷”小冰的核心技术与聊天机器人技术的发展趋势!
工程师测评|OKMX8MP-C开发板部分功能实测
单片机的功能侧重于测量和控制什么
云计算服务未来前景如何?
盘点8月份国内5G技术发展