在 Android/Dalvik 環境引入 precompiled class 的實驗

延續筆者去年的紀錄「當 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"。

為了降低實做的複雜度,筆者最早採用 LLVMIcedTea 作為系統框架,不過一直到今年春節,整體進度還是陷入膠著的狀態。現在則引入 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),大多可進一步給予提昇。這僅是初步的整合實驗數據,還需要更多分析與進行實做。


About this entry


  1. Unknown 2010年5月26日 上午8:27

    Cool! BTW, the score of LU is interesting.

     
  2. Unknown 2010年5月26日 上午9:02

    Some more questions. Which native interface do you use? Can pre-compiled classes be load dynamically?

     
  3. jserv 2010年5月26日 中午12:43

    We still use JNI. So, it's room for improvements.

     
  4. Unknown 2010年7月26日 晚上11:26
    網誌管理員已經移除這則留言。
  5. Alex 2010年8月2日 下午4:32

    Jserv 你好,
    我是清華大學的研究生,最近也在做android的compiler方面的研究。
    請問你們的SciMark 2.0是自己改寫成android version的嗎?
    因為我看它的官網上面只有Java version。
    如果不是,可以分享如何取得嗎?
    感激不盡,謝謝

     
  6. jserv 2010年8月2日 晚上11:42

    To Alex,

    請依據 Android 原始程式碼裡面,packages/app/ 目錄那些範例,將 SciMark 2.0 放入其中即可。另外,在 COSCUP 上,我們預計會公開 (open source) 0xlab 自製的 Android Benchmark Suite -- 0xbench,裡面包含 SciMark + UI

     
  7. Unknown 2010年8月20日 下午5:32

    Jserv 你好:

    我在从事Android平台的性能优化工作。过去的工作主要是使用ARM指令来优化一些底层库;最近的工作重心逐步转移到上层,开始接触一些JAVA方面的东西。看完你的文章,受益非浅。我想知道“預先編譯 (pre-compile) 這些 class/method,居中透過 JNI (Java Native Interface) 讓 Dalvik VM 存取”是如何实现的?我在JAVA方面所知甚少,还忘不吝赐教

     
  8. Unknown 2010年12月9日 下午2:19

    Hi Jserv,请问你们的pre-compile是在系统运行前编译,还是执行过程中统计程式频繁执行的部分,再compile(这个应该是jit)?另外,有和froyo jit做比较的数据?

     

張貼留言