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