1. 程式人生 > >Qt Embedded效能優化詳解

Qt Embedded效能優化詳解

Qt Embedded是挪威公司的圖形化介面開發工具QT的嵌入式版本,它通過QTAPI與LinuxI/O以及Framebuffer直接互動,擁有較高的執行效率,而且整體採用面向物件程式設計,擁有良好地體系架構和程式設計模式.

Qt EmbeddedQt一樣,在4.5版本之後提供了三種不同的授權協議GPL, LGPL和Commercial。長久以來,雖然使用Qt Embedded在作開發,但對Qt Embedded的效能方面不甚關心,並且因為抱著對qtsoftware的信心,也沒仔細去了解如何優化Qt Embedded。直到前段時間,參加了某個全國嵌入式大賽,使用了Qt Embedded4

.5.0在s3c2410平臺上,竟然出現了卡機的現象。對於嵌入式開發來說,資源是極為重要的,而現在看來,Qt變得越來越龐大,越來越耗費稀缺的裝置資源,這時,優化就變得格外重要了。在Qt Embedded的文件中有關於效能優化的介紹,我做了簡單地翻譯,希望能給在嵌入式領域使用Qt Embedded的開發者有所幫助。

Qt 效能優化

當在資源稀缺的裝置上開發嵌入式應用程式時,Qt for Windows CE 和Qt for EmbeddedLinux通過調整一系列引數的開啟或關閉來記憶體及CPU的需求。這些選擇引數方法的範圍主要在程式設計風格,連結方式及記憶體分配。

著重注意的是,最直接節省資源的辦法是在編譯時去掉不需要的特性。詳細可以見文件中的fine tuning features部分。

1、程式設計風格

2、靜態連結vs動態連結

3、替換記憶體分配方式

4、繞過後備存放區

程式設計風格

與其選擇隨時地創造對話方塊和控制元件當它們需要時,並且在不再需要時刪除它們,不如一次性地建立,同時在需要的時候使用QWidget::hide()和QWidget::show() 功能函式。為了避免應用程式啟動的緩慢,應該推遲對話方塊和控制元件的建立直到需要的時候。所有這樣將改善CPU的效能,所需要付出的只是更多的一點記憶體,但這會加快執行的效率。

動態 Vs 靜態連結

許多CPU和記憶體是通過ELF (Executable and Linking Format)連結程序,重大的節省可以通過靜態編譯程式的方式實現;而不像是在實際執行中,採集與Qt庫有關的部分並且動態連結,所有的應用程式將被建立成一個獨立的執行檔案,這個檔案採用靜態方式連結到Qt庫上。

這些將改善程式啟動時間和減少記憶體佔有率,但前提它會損害靈活實用的特性(一旦增加新的應用部分,必須重新編譯一個獨立的執行檔案)和程式健壯性(假如一個應用部分有bug,將危害到其他的應用部分)。

建立一個靜態編譯

為了將Qt編譯成為一個靜態庫,在編譯時採用-static引數:

  1. ./configure –static 

為了將應用程式套裝建立為一個一體化的應用,應當設計各個應用作為單獨的控制元件(或者控制元件集)並儘可能地使用最少的程式碼量在main()函式。然後,設計一個獨立的應用程式可以提高其他應用程式見互動的方法。Qt Extended platform就是採用典型的例項:它既可以使用一系列動態連結執行建立,也可以作為單獨的一個靜態的獨立應用程式。

需注意的時,程式仍將動態地連結標準C庫以及其它庫,因為在目標平臺上可能會有其他的應用程式使用它們。

當安裝最終客戶端應用程式時,這個方式不一定是個選擇,但是當在為一個受CPU和記憶體限制的裝置開發一個單獨的應用程式套裝時,這個選擇是十分有益的。

替換記憶體分配方式

在一些平臺上,那些運用C++編譯的庫,在使用“new”和“delete”操作方面有十分差的效能。未來改善記憶體分配的效能,可以通過以下的功能函式替代實現:

  1. void *operator new[](size_t size)  
  2.  {  
  3.      return malloc(size);  
  4.  }  
  5.  void *operator new(size_t size)  
  6.  {  
  7.      return malloc(size);  
  8.  }  
  9.  void operator delete[](void *ptr)  
  10.  {  
  11.      free(ptr);  
  12.  }  
  13.  void operator delete[](void *ptr, size_t)  
  14.  {  
  15.      free(ptr);  
  16.  }  
  17.  void operator delete(void *ptr)  
  18.  {  
  19.      free(ptr);  
  20.  }  
  21.  void operator delete(void *ptr, size_t)  
  22.  {  
  23.      free(ptr);  
  24.  } 

以上這些例項顯示了必要的程式碼採用C的記憶體分配。

繞過後備存放區

當執行時,Qt使用了後備存放區。比如,一個繪圖快取,可以減少閃爍和支援如重疊的圖形操作。

一般,預設的流程是這樣的,對於每個客戶端,將自己的控制元件傳入記憶體,同時,服務端負責將這些內容從記憶體中取出並在螢幕上繪製。但是有些硬體是眾所周知的,同時已經有嵌入式軟體的案例,這些對於繞開後備存放區是很有幫助的,可以執行客戶端直接地熟練地操作硬體。這裡有兩種方式來實現直接繪製:第一種方式是對每個控制元件使用Qt::WA_PaintOnScreen視窗屬性,另一種是使用了QDirectPainter類來儲存幀快取的區域。想獲取更多資訊,可以參考architecture 文件部分的direct painting細節。