本期為大家帶來一篇嵌入式開發性能優化案例,感興趣的小伙伴可以關注作者一起學習哦~
本期推
薦
介紹:本專欄介紹嵌入式USB開發,理論結合實踐,不單純講USB協議,而是以具體的實例進行講解。
前言
我們之前進行了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_SDA
2.使用寄存器變量
頻繁操作的局部變量盡量使用寄存器進行緩存,避免反復從內存去加載,寄存器直接操作速度快很多。
register unsigned int data;
3.空間換時間 8次for循環改為 直接8次操作
其實在memcpy等處理中也是類似操作,比如連續8次讀寫組合一起,再循環。以減少for判斷次數,也利于內部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; //輸出數據
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嵌套改為一層for
For嵌套導致多重循環嵌套判斷,浪費時間,順序執行一般是優于分支處理的。
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位數據
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寄存器,進一步優化速度。
原文地址:http://www.1cnz.cn/d/2101849.html
版權說明:
本內容為作者發布至電子發燒友平臺原創文章,相關創作版權歸原作者所有,如未經作者授權,禁止轉載!
更多熱點文章閱讀
原文標題:【專欄精選】嵌入式開發極致性能優化案例
文章出處:【微信公眾號:電子發燒友論壇】歡迎添加關注!文章轉載請注明出處。
-
電子技術
+關注
關注
18文章
890瀏覽量
55976 -
電子發燒友論壇
+關注
關注
4文章
197瀏覽量
1085
原文標題:【專欄精選】嵌入式開發極致性能優化案例
文章出處:【微信號:gh_9b9470648b3c,微信公眾號:電子發燒友論壇】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論