QNAP NAS

QNAP online resources collection

Image
QNAP is the famous private cloud solution provider, the main product is NAS (Network attach Storage), this article collect QNAP online resources and help QNAPer / NAS beginner quickly know how to select NAS and find application information, if any suggestion website, welcome to comment and share with us. QNAP website  https://www.qnap.com/en/ Topic include NAS, Operation System, Application, Tutorial / FAQ , Forum and Customer Service.

x86 架構 Android 應用程式的優化技巧與訣竅

x86 架構 Android 應用程式的優化技巧與訣竅

Intel 公司非常重視如何為開發人員提供可在 Intel 架構上運作正常 (甚至是效能最佳) 的 Android 應用程式。雖然 Intel 致力於社群層級,包括最佳化 Dalvik Java、V8 引擎及 Bionic C;為程式碼基底做出貢獻;並為 IA 提供 32 與 64 位元核心的版本;但 Intel 也同樣創造多種新工具來協助 Android 開發人員。上述工具主要用於提升效能,以超越 x86 預設的 ARM 轉譯層提供的效能:libhoudini
但是首先應選擇正確的工具。建立 Android 應用程式有三種常見的方法。
  1. 使用 Android SDK API 編譯 Java,以便在 Dalvik VM 中執行。附註:針對 ART 的說明文章近期之內即可在 Android L 取得。
    使用最新的 SDK 以顧及最大的差異,雖然您可能比較注重針對高解析度螢幕所配置的記憶體。最值得注意的是,如果藉由 Intel® HAXM (需要將 Intel® 虛擬技術與 XD 設為開啟) 提升 Android 模擬軟體的速度,將可加快測試的速度。
  2. 聚焦於網頁的 HTML5 與 JavaScript。有關開放原始碼 Android 資訊,請參閱 Android-IA 網站
  3. 建立或移植的 NDK (以 C++ 撰寫)。如果有密集使用處理器的功能或已有 C++ 程式碼,那麼這是比較理想的方法。原生 C++ 程式碼通常 (不一定) 會因為以「原生」的語言溝通而使執行速度較快,因為程式碼在執行之前會編譯為二進位,而且不需要解譯為機器語言。
本文將聚焦於最佳化以 NDK 為基礎的應用程式。這些應用程式可能僅使用 C/C++ 程式碼,或可能包含第三方程式庫及 / 或組合碼。
附註:如果尚未擁有 Android 開發環境 (IDE),新工具套件 Intel® INDE (Intel® Integrated Native Developer Experience) 將載入選取的 Android IDE 並下載及安裝多種 Intel 工具,以便協助您製作、編譯、疑難排解及發佈 Android 應用程式。按一下這些連結以瞭解一系列有關註冊及安裝 Intel® INDE 及使用 Eclipse* IDE 進行設定的方法。以及有關設定 NDK 與 SDK*、Eclipse*,以及執行於模擬器 (包括如何加快其速度) 或 Intel® 架構裝置的影片連結。
在高階部分,NDK 開發包括以下步驟及最低變更,以便在 x86 架構上運作。
  1. 建立 Android 專案及 jni 資料夾。編輯 Application.mk 以顯示 APP_ABI = all (如果檔案大小是 ARM* 及 x86 允許的,即可放入相同的套件中) 或 x86。附註:APP_ABI 設定也會影響浮點運作操作 - 請參閱以下內容。
  2. 程式碼。任何原生 (C++) 程式碼皆可重複使用。重新撰寫所有內嵌組譯碼或 ARM 特定程式碼。使用 javah 建立 JNI/ 原生程式碼標頭檔。在 Windows 標準 C++ 慣例與 Java/JNI 之間進行解譯時,請務必使用 JNIEXPORT 與 JNICALL 巨集。
  3. 編譯 / 建置程式庫 (呼叫會產生 .so 程式庫並將它們放入適當的專案目錄)。使用「ndk-build APP_ABI = X86」以及少數幾個建置旗標變更 - 請參閱以下內容。另外,請務必重新編譯所有的第三方程式庫。
  4. 從 Java 呼叫。在 Java 中宣告原生 (C++) 函式呼叫,並使用 System.loadlibrary() 載入共用的程式庫。
  5. 除錯。執行 ndk-build 並將資訊清單設為可除錯,即可使用 ndk-gdb 除錯。請確定 adb 目錄已加入至 PATH,且只有一個目標正在執行。
除了基本的「移植」之外,還有一些最佳化可以使用,

最佳化秘訣:

  1. 使用 Intel® HAXM 硬體輔助模擬,加快以軟體為基礎的 Android 模擬器。Intel® HAXM 需要將 Intel® 虛擬化技術 (Intel® VT) 及 XD 設為開啟。
  2. 依據您的檔案大小限制,設定 APP_ABI = x86 (建立一個內含所有二進制檔案的 APK) 或 = armeabi armeabi-v7a x86。(注意,x86 與 armeabi-v7a-x86 (在某種程度上) 同樣包含硬體浮點)
  3. 在編譯過程中,使用 gcc "-malign-double"。(這用於記憶體對齊 - 另請參閱 #9)
  4. 在編譯過程中,新增適當的 CPU 執行緒旗標
    針對 Intel® Atom™ 處理器超執行緒功能,可嘗試 -mtune=atom -mssse3 -mfpmath=sse
    針對非超執行緒 (BYT、SLM、Merrifield),使用 -mtune=slm -msse4.2 -mfpmath=sse
    使用 -march= 以限制指定的 CPU (mtune 可執行於更多的機型,但是僅針對列出的類型進行最佳化)。
    -mavx 尚無法在 Atom 上使用。
  5. 使用 Little Endian (預設使用 NDK)。ARM* 支援 Big 與 Little Endian,Intel® Atom™ 僅支援 Little,因此請檢查您的 gcc 旗標。
     
  6. 使用 v 4.8 的 gcc。注意這兩個工具鏈路徑 (android-ndk\toolchains\arm-linux-androideabi-4.8 以及 x86 android-ndk\toolchains\x86-4.8
  7. 請務必使用正確的 JNIEXPORT 方法簽章,將輸入方法設定至原生碼 - (符合標頭檔的函式簽章,以確保原始碼可在 Windows 上編譯*)。
    JNIEXPORT void JNICALL Java_ClassName_MethodName
  8. 編譯之後,請檢查系統記錄,確定目標原生程式庫已在執行階段順利載入。(這將會在記錄中顯示為 "added shared lib //<path>"
  9. 強制對齊記憶體,以避免載入錯誤及網路封包問題。ARM 佔用 24 位元組,但需要 8 位元組對齊才能使用 64 位元變數,而 x86 佔用 16 位元組,因此請盡量確保資料結構的 16 位元組對齊。接著,從該結構載入至 XMM 暫存器時,請使用對齊搬移 (MOVAPS、MOVNTA)。請參閱減少非對齊記憶體存取的影響
  10. 由於 Intel® Atom™ 處理器沒有 L3 快取,因此請將資料直接寫入至主記憶體 (串流儲存指令 MOVNTPS、MOVNTQ);如此一來,也能避免快取收回時發生「dirty writeback」以節省使用的頻寬。
  11. 避免因為有限的 L2 快取而造成停滯。除了特定實例之外 (資料載入與儲存至相同的位址,相同大小的運算元,以及從一般目的暫存器完成),Intel® Atom™ 處理器上的負載將會在寫入至快取時停滯幾個週期。另外,SSE 運算元儲存 (來自 xmm 暫存器) 永遠不會轉送至後續負載。
    因此針對轉送與非轉送的情況,應嘗試在暫存器中運算資料,在 xmm 暫存器中執行加總。以 mp3 解碼器為例,有一個「窗型」迴圈在暫存器中累加 / 運算總數,然後加總各暫存器的總數。
    如此一來,從 16 位元組儲存到 pSum 陣列,以及來自 pSum 的後續 4 位元組負載之間便會發生阻隔的儲存轉送停滯。為避免發生此問題,可使用 HADDPS 指令或一系列的 add 和 shuffle,在 xmm 暫存器中運算水平加總。(但請注意,HADDPS 序列在 Intel® Atom™ 處理器上速度較快,但在 Intel Core 其他版本的處理器上則較慢)。利用 SSE min 和 max 指令執行超出 16 位元範圍的樣品修剪。
  12. 使用前請先將整個 XMM 暫存器初始化 (MOVLPS、MOVHPS、PINSRW),因為有些指令僅載入部分的暫存器,如此會因為仍殘留於另一部分的程式碼而造成問題。
  13. 閱讀有關最佳化 SIMD 指令 (Intel SSE vs. ARM* NEON*) 的文件。考慮使用程式庫NEONvsSSE_5.h 可在此取得 (取代 arm_neon.h)。此外,此文件還提到在使用常數時會有效能損耗 (如果可能的話,不要在迴圈中進行初始化,而是以邏輯 / 比較運算取代),並且避免序列實作 (使用向量化)。
  14. divide 與 sqrt 運算耗用過多週期,可利用 table-lookup 運算、reciprocal approximation (RCPPS 指令) 或 Newton-Raphson 序列予以取代。
  1. 注意浮點呼叫。使用 Float 取代 Double (因為 Double 通常使用 SW lib 常式)。Float 不僅速度較快,還能節省 Intel® Atom™ 處理器的記憶體頻寬。除此之外,APP_ABI 設定是否使用 SW (armeabi) 或 HW (X86, armeabi-v7a x86) 浮點。您不會永遠想要使用 x86 演算法計算整個 HW FPU 運算。(舉例來說,在 integer 程式碼中除以平方是快速的右移位運算,但對於 Android 最佳化而言,應用倒數相乘取代 (y=x*.5 取代 y=x/2)
  2. 減少小型函式的負荷。在各種場合使用 Inline 函式,包括參數傳遞、新堆疊框設定 / 舊堆疊框還原 / 保留呼叫程式的堆疊框、將位址放入堆疊;傳回值呼叫以及返回函式。另請參閱 Intel® 64 與 IA-32 架構最佳化參考手冊
您有其他最佳化的方式嗎?請在下面發表評論。
有關編譯器最佳化的更完整資訊,請參閱最佳化聲明
類別:
標籤:

Comments

Popular posts from this blog

How to use MongoDB on QNAP NAS ?

How to setup influxDB and Grafana on QNAP NAS ?

How to use PostgreSQL on QNAP NAS ?

QNAP QVR Pro Client user guide

How to setup GPU on QNAP NAS (QTS 4.3.5+)

How to use QNAP IoT solution - QIoT Suite

How to use Home Bridge on QNAP NAS ?

卸任倒數 宏碁突圍再出奇招 不轉型雲端 施振榮:我就是罪人