延續筆者去年的紀錄「當 Compiler 遇上 Mobile」,最近我們又獲得一些進展,是在 Android 的 Dalvik 虛擬機器環境中,引入 pre-compiled class 的實驗,除了可改善執行時期的效能、記憶體使用量外,另外就是避免在「反組譯並修改 Android 應用程式實例」一文可見的資訊保護議題。
其實十幾年前,在 Java 平台中就有相當多團隊提出可行的方案,而世界上第一個開放原始碼的 Kaffe 虛擬機器專案,早在 1999 年即提出實做 "Kaffe/GCJ integration",成功地將 GCJ (GCC for Java) 自 Java class/source 編譯得到的機械碼,當作 pre-compiled shared library,讓 Kaffee VM 讀取,預期可有效改善執行效能並縮減起始時間。GNU Classpath 專案主持人 Mark Wielaard 在 LWN 的文章 "GCJ - past, present, and future" 提到相關的歷史與技術背景,最早可回溯到 Cygnus solutions 時期 (RedHat 尚未併購) 的 GCJ 計畫提案 -- "A Gcc-based Java Implementation"。
為了降低實做的複雜度,筆者最早採用 LLVM 與 IcedTea 作為系統框架,不過一直到今年春節,整體進度還是陷入膠著的狀態。現在則引入 Java2C 搭配 PGO (Profile-Guided Optimization) 與統計模型,嘗試分析運行於 Dalvik VM 的 Android activity / system server,佔用系統資源最頻繁的項目,並預先編譯 (pre-compile) 這些 class/method,居中透過 JNI (Java Native Interface) 讓 Dalvik VM 存取。不過,實務上來說,不是將所有 class/method 都編譯為原生機械碼,就會帶來效能提昇,相反地,後者往往讓系統陷入更差的效能。目前 Eclair 裡面的 Dalvik VM 雖然沒有完整的 JIT compiler,但其 fast interpreter for ARM 的確做了頗多 threaded interpreter 的改進,考量到 I-cache, paging, 與 branch prediction,若我們不思量 Java / Android Dalvik 應用程式的執行時期行為,只是一味作編譯轉換,很可能只是編譯極少被執行,或者完全不會被執行到的程式碼,因此加重執行時期的負擔,而最該被優化的部份,受限於不完整的 source-to-source 轉換,有顧此失彼的疑慮。
於是,找出系統中最該被優化的部份,並考量到正確性與相容度,就是我們的首要研究議題,筆者採用知名的 SciMark 2.0 作為量化分析的指標。以下是在 Qualcomm MSM7x25 硬體平台 (arm1136j-s) 的效能評比,ARM11 的時脈是 528 MHz,ARM Linux 版本為 2.6.29.6-0xlab:
由上可見,在 SciMark 2.0 的各項評比中,Pre-compiled class 執行效能都較 Android Dalvik fast interpreter for ARM 給予一定程度的改良,並且透過 FDO (Feedback Directed Optimization),大多可進一步給予提昇。這僅是初步的整合實驗數據,還需要更多分析與進行實做。
8 意見:
Jump to comment form | comments rss | trackback uri