做電子發(fā)燒友技術(shù)探索官,分享你的原創(chuàng)電子行業(yè)文章!
本期為大家?guī)?lái)一篇嵌入式開發(fā)性能優(yōu)化案例,感興趣的小伙伴可以關(guān)注作者一起學(xué)習(xí)哦~
本期推
薦
專欄作者:嵌入式USB開發(fā)(點(diǎn)擊查看作者主頁(yè))
介紹:本專欄介紹嵌入式USB開發(fā),理論結(jié)合實(shí)踐,不單純講USB協(xié)議,而是以具體的實(shí)例進(jìn)行講解。
前言
我們之前進(jìn)行了TFT刷屏測(cè)試確認(rèn)了基本功能。刷屏速度是決定GUI顯示幀率最根本的一環(huán),只有優(yōu)化到極致的刷屏速度,才能有基礎(chǔ)實(shí)現(xiàn)更好效果的GUI。本篇就進(jìn)行刷屏的優(yōu)化,其實(shí)其思想是通用的,對(duì)于其他代碼也可以參考。
1.減少if條件判斷
if等條件判斷會(huì)導(dǎo)致分支處理,一方面會(huì)增加指令,尤其是跳轉(zhuǎn)指令一般執(zhí)行時(shí)間比一般指令長(zhǎng),另外也會(huì)影響流水線和cache。
if(Data&0x80)
LCD_SDA_SET; //輸出數(shù)據(jù)
else LCD_SDA_CLR;
改為串行操作
#define LCD_SDA_SET_VAL(val) LCD_CTRLB->BSRR=val;LCD_CTRLB->BRR=val^LCD_SDA
2.使用寄存器變量
頻繁操作的局部變量盡量使用寄存器進(jìn)行緩存,避免反復(fù)從內(nèi)存去加載,寄存器直接操作速度快很多。
register unsigned int data;
3.空間換時(shí)間 8次for循環(huán)改為 直接8次操作
其實(shí)在memcpy等處理中也是類似操作,比如連續(xù)8次讀寫組合一起,再循環(huán)。以減少for判斷次數(shù),也利于內(nèi)部cache流水線處理,有一些cpu還有burst處理,這也是有利的。
inline void SPI_WriteDataF(unsigned char Data)
{
#if 0
unsigned char i=0;
for(i=8;i>0;i--)
{
if(Data&0x80)
LCD_SDA_SET; //輸出數(shù)據(jù)
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.使用內(nèi)聯(lián)函數(shù)減少函數(shù)跳轉(zhuǎn)時(shí)間
inline void SPI_WriteDataF(unsigned char Data)
函數(shù)跳轉(zhuǎn)需要時(shí)間,減少函數(shù)調(diào)用即可節(jié)約時(shí)間,尤其頻繁調(diào)用的函數(shù)效果明顯,但是可能增加存儲(chǔ)空間。
5.減少for循環(huán)嵌套 雙重for嵌套改為一層for
For嵌套導(dǎo)致多重循環(huán)嵌套判斷,浪費(fèi)時(shí)間,順序執(zhí)行一般是優(yōu)于分支處理的。
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
{
LCD_CS_CLR;
LCD_RS_SET;
SPI_WriteDataF(Color>>8); //寫入高8位數(shù)據(jù)
SPI_WriteDataF(Color); //寫入低8位數(shù)據(jù)
LCD_CS_SET;
}
}
6.減少函數(shù)調(diào)用層級(jí)
函數(shù)調(diào)用影響流水線,并且需要額外的上下文處理時(shí)間
Lcd_ClearF中直接調(diào)用SPI_WriteDataF不再調(diào)用函數(shù)LCD_WriteData_16Bit
7.使用匯編進(jìn)行優(yōu)化
這個(gè)實(shí)際看情況建議先用其他方式進(jìn)行優(yōu)化,因?yàn)槿斯ぞ帉憛R編代碼不一定比編譯器編寫的好,除非非常熟悉匯編并且有明確的優(yōu)化方向。
8.速度測(cè)試
循環(huán)刷屏使用定時(shí)器記錄執(zhí)行多次刷屏的時(shí)間,代碼見附件。
9.編譯器速度優(yōu)化選項(xiàng)
編譯器-Ofast優(yōu)化
執(zhí)行時(shí)間分別是
660ms,782ms
我們優(yōu)化后的代碼快15.6%
編譯器-O2優(yōu)化
執(zhí)行時(shí)間分別是661ms,908ms
我們優(yōu)化后的代碼快快27.2%
-從上可以看出不管用什么編譯器優(yōu)化,經(jīng)過上面方式人工優(yōu)化后的代碼都不差不多,660和661,說明編譯器已經(jīng)無(wú)法對(duì)我們優(yōu)化后的代碼再進(jìn)行優(yōu)化
- 說明我們?nèi)斯?yōu)化的代碼不使用編譯器優(yōu)化也有很好的速度性能。
-不同的編譯器優(yōu)化對(duì)原來(lái)的代碼影響較大-ofast執(zhí)行時(shí)間從908變?yōu)榱?82。
-哪怕是采用-ofsat編譯器優(yōu)化,我們?nèi)斯?yōu)化的代碼依然還有比編譯器優(yōu)化的代碼快15.6%,所以編譯器優(yōu)化無(wú)法替代人工優(yōu)化。
-只有從設(shè)計(jì)角度去優(yōu)化,避免依賴編譯器優(yōu)化才是根本方案。
總結(jié)
1.優(yōu)化應(yīng)該從設(shè)計(jì)上去優(yōu)化而不是依賴編譯器,應(yīng)該先找大頭,優(yōu)先設(shè)計(jì)原理,算法上去優(yōu)化,最后采取進(jìn)行匯編等底層的優(yōu)化,后者成本大效果不明顯不具備可移植性等,前者成本小效果明顯,不依賴于編譯器。
2.建議寄存器名字和手冊(cè)對(duì)應(yīng)比如gpio的io鎖定寄存器,頭文件中是LOCK手冊(cè)里是LCKR
2.對(duì)于IO操作最好設(shè)置LOCK ODR寄存器,這樣可以指定bit直接寫值而其他位不修改,而不需要if else判斷分別配置BRR 和BSRR,可以直接操作ODR寄存器,進(jìn)一步優(yōu)化速度。
原文地址:http://ttokpm.com/d/2101849.html
版權(quán)說明:
本內(nèi)容為作者發(fā)布至電子發(fā)燒友平臺(tái)原創(chuàng)文章,相關(guān)創(chuàng)作版權(quán)歸原作者所有,如未經(jīng)作者授權(quán),禁止轉(zhuǎn)載!
更多熱點(diǎn)文章閱讀
原文標(biāo)題:【專欄精選】嵌入式開發(fā)極致性能優(yōu)化案例
文章出處:【微信公眾號(hào):電子發(fā)燒友論壇】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
-
電子技術(shù)
+關(guān)注
關(guān)注
18文章
873瀏覽量
55757 -
電子發(fā)燒友論壇
+關(guān)注
關(guān)注
4文章
197瀏覽量
1040
原文標(biāo)題:【專欄精選】嵌入式開發(fā)極致性能優(yōu)化案例
文章出處:【微信號(hào):gh_9b9470648b3c,微信公眾號(hào):電子發(fā)燒友論壇】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論