libacc : Android 2.0 內建的輕量級 C Compiler

Android 2.0 (Eclair) 原始程式碼已於一個月前釋出,在目錄 system/core 下有個 libacc 的子項目,這是開發者修改自 Fabrice Bellard 的大作 OTCC (Obfuscated Tiny C Compiler),以 C++ 與 Android 的執行時期函式庫重寫。libacc 的功能是提供給 Android 2.0 的 RenderScript 一個 C-like 語法的描述,如此一來,開發者可撰寫高效能的視覺效果與動畫,不過這部份並未完成,詳情可參考 "Android renderscript, more info' and an example application" 一文。

關於 libacc 的整合部份,可參考 frameworks/base/libs/rs 目錄下的兩個檔案:

  • rsScriptC.cpp
  • rsScriptC_Lib.cpp
筆者準備了一份可單獨執行於 GNU/Linux 環境的套件:"libacc.tar.bz2",除去 Android 的相依性並補上 Makefile,測試方式如下:
libacc$ make
g++ -I./include -DHAVE_PTHREADS -c acc.cpp
gcc -I./include -DHAVE_PTHREADS -c hashmap.c
gcc -I./include -DHAVE_PTHREADS -c logd_write.c
g++ -I./include -DHAVE_PTHREADS -c tests/main.cpp
g++ -I./include -DHAVE_PTHREADS -c tests/runtimeTest.cpp
g++ -o main \
acc.o \
hashmap.o \
logd_write.o \
main.o \
-ldl
g++ -o runtimeTest \
acc.o \
hashmap.o \
logd_write.o \
runtimeTest.o \
-ldl
libacc 的 Code generator 支援以下硬體架構:
  • x86 / IA32
  • x86_64
  • ARMv5
以 IA32 的環境為例,可透過測試程式來驗證 libacc: (參數 -R 表示作執行的動作)
libacc$ ./main -R tests/data/hello.c
Executing compiled code:
Hello, world
result: 0
其中 tests/data/hello.c 的內容為:
libacc$ cat tests/data/hello.c
int main() {
printf("Hello, world\n");
return 0;
}
若平台是 ARM 的話,還可以支援反組譯輸出,libacc 是 RenderScript 背後很重要的基礎建設,允許動態編譯 Android Graphics 的 RenderScript,輸出成機械碼並執行。參考檔案 tests/runtimeTest.cpp 可得知 RenderScript 的寫法,整個 libacc 可內嵌於程式中,比方說:
const char* text = "void op_int(int a);\n"
"void op_float12(float a, float b, float c, float d,\n"
" float e, float f, float g, float h,\n"
" float i, float j, float k, float l);\n"
"void script() {\n"
" globalVar += 3;\n"
" op_int(123);\n"
" op_float12(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0);\n"
"}\n";
這個字串經過 libacc 的函式呼叫後,可得到以下的編譯與執行結果:
libacc$ ./runtimeTest
Executing script:
op_int(123)
op_float12(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12)
After script globalVar = 20
目錄 tests 還包含可在 Android 環境執行的自動測試 Python script。

read on
Posted 張貼者: jserv 於 下午4:53 on 2009年12月9日 星期三 | 3 意見
Filed under: , ,
 

在 0xdroid 充分發揮 Beagleboard/OMAP3 的硬體特性

最近 0xlab 的開發者持續改善 0xdroid,在 gitorious 的團隊排名維持在前五名的活躍程度,除了稍早提及針對 ARMv7 與底層軟體架構的改進外,0xdroid 也加入了對 Beagleboard / TI OMAP3 硬體更充分的支援。現在與多媒體處理相關的架構圖可參考以下:

紅色的部份是 Android 的 framework 層面 (Media framework, Media server),而藍色則是實做 framework 所需服務的元件 (如 OpenCore),剩下綠色的地方自然是 0xlab 關注、與硬體平台相關的元件,這裡簡要列出:

  • libaudio : 透過 ALSA 處理 Audio In/Out,針對 TI OMAP3 平台做了調整
  • libcamera : 以 V4L2 (Video For Linux) API 為基礎,提供上層 Android framework 對 camera 所需的硬體支援。透過 TI OMAP3 平台的 video overlays 作 preview 影像處理,並善用 TI DSP 的能力作 JPEG 處理
  • libopencorehw : 銜接 OpenCore,允許透過 TI OMAP3 平台的 video overlay 作高效能顯示處理
  • liboverlay : 讓 libcamera 與 libopencorehw 共用的 video overlay 操作模組
  • TI DSP / OMX : 透過 OpenMAX 標準介面,使用 TI DSP 實做的硬體多媒體 codec 運算
  • FFmpeg / OMX : 透過 OpenMAX 標準介面,使用針對 ARMv7/NEON 優化的硬體多媒體 codec 運算,這部份採納 FFmpeg 的基礎
目前上述的硬體特有的元件已有初步實做,待驗證與調整 HAL 後,就會陸續整合到 0xdroid 的公開 repository,至於開發相關的議題,可到 0xlab 的郵件討論群組 0xlab-devel 交流,謝謝。

read on
Posted 張貼者: jserv 於 下午2:38 on 2009年9月18日 星期五 | 0 意見
Filed under: , , , , ,
 

在 Beagleboard 上比較 Dalvik 與 CVM-jit 的效能

前文「對 String 操作的改進」與「Android Dalvik VM vs. Java VM」談及基於 CVM 引擎的 Java VM 與 Dalvik 的效能差異後,最近 0xlab 內部也因為挑選硬體平台,持續分析 Embedded CaffeineMark 一類量化效能的報告。參考的硬體組態是 OMAP3/ARMv7 500 MHz,粗略的效能評比如下圖:

Dalvik 取自 0xdroid (cupcake + backported from donut),而 CVM-jit 則源自 phoneME CVM svn r19264,整體分數為:

  • Dalvik VM : 1034
  • CVM + jit : 7526
CVM 的組態設定:
  • cached constant
  • cached constant inlining
  • array init bounds check elimination
  • Hardware fpu = NEON
  • AAPCS
當然 Just-In-Time compiler 不是萬靈丹,從上述效能評比可發現,CVM 在若干地方做了重要的微調,比方說透過 CNI 實做若干 class library 的關鍵 method,以及善用硬體 floating-point 操作 (注意:本組態未引入 ARMv6 與 ARMv7 的 Thumb2/Thumb-EE 指令集)。儘管 Android 團隊中 Dalvik 開發者 fadden 在郵件討論群組談及
Four String methods -- charAt, compareTo, equals, and length -- are
"inlined" by the VM, and are not going to get much faster.

There are probably a few others that could benefit from this
treatment, but I'm guessing that most string-centric processing in
Java will likely be dominated by the cost of String allocations. (The
above weren't inlined because of a measured performance need -- the
inlining was an experiment that needed a test subject.)
Dalvik 理論上可施加這些優化技術 (string allocation / native method inlining),不過目前開放的實做中,尚未引入 (至少在 donut branch 中)。即便在保持 pure interpreter 的架構下,現有 class library 與 GC (garbage collector) 仍可作些調整,以改善 Android 的應用程式執行效能與 (圖形應用導向的) 使用者互動反應表現。

read on
Posted 張貼者: jserv 於 上午10:54 on 2009年8月25日 星期二 | 4 意見
Filed under: , , , ,
 

SDL 在 Android SurfaceFlinger 的初步移植

本日仍在追蹤 0xdroid 的穩定性與效能議題,進行壓力測試時,順便將知名的 SDL 函式庫移植到 Android window system,更具體來說,就是允許在 Android Surface Manager (SurfaceFlinger) 上運作 SDL 應用程式,背景知識請參考 0xlab 圖形處理達人 olv 的簡報 "Introduction to Android Window System" (PDF)。依據 olv 提供的範例 SurfaceFlinger 操作程式,libSDL 可很快地加上 Android video backend,接著透過 libui 的 EventHub 取得來自 Linux input subsystem 的事件。現在初步的移植成果可參考下圖:
上圖展示一個以 SDL 撰寫的 NES 任天堂模擬器,顯示更新於新建立的 Android Surface 上,筆者將該 Android surface 的起始座標位置挪到 (100, 100),並設定其半透明度值,載入筆者最愛的泡泡龍 (Bubble Bobble) 遊戲 ROM。目前僅算堪用的狀態,未來要考慮到 Android Surface 限制 color space 為 RGB565 (針對 16-bit depth 顯示所做的優化限制),勢必得在 libSDL 引入若干 color space 轉換的繁瑣運算,可透過 ARM NEON 一類的硬體加速機制去改善效能。

read on
Posted 張貼者: jserv 於 下午10:37 on 2009年8月13日 星期四 | 1 意見
Filed under: , ,
 

對 String 操作的改進

之前的文章「Android Dalvik VM vs. Java VM」提及純 interpreter 的 Dalvik VM 與具備 Just-In-Time compiler 的 JBend JVM (基於 CVM 引擎) 的效能比較,以修改過的 Embedded CaffeineMark 作為量化的依據,可發現 String 測試項目差了一個數量級 (491 vs. 5109),整體的分數是 1:4.18 (1811:433)。稍早 ansoncat 做了初步分析:

「這部分應該是由於在 CVM 中,使用了 CNI 來實作 String class 的重要操作 ... 因為 String 的分數拉高了平均,其它 benchmark 的效能差異會比平均分數的差異大的多」
目前 0xdroid 在不更動 Dalvik VM 實做的前提 (後續再談改進的途徑),對 bionic libc 的 string 相關函式作調整,移植來自 CodeSourcery/ARM 的 ARMv7 Thumb2 優化實做,就 micro-benchmark 的角度來說,效能改進約有 25% (初步分析,要考慮到不同的環境配置),但整合到 Android/Dalvik 的表現又是如何呢?筆者的實驗結果如下: (score 大者為佳)

測試環境是 Beagleboard (500MHz) 運作 0xdroid,以 ARMv7 GNU Toolchain 編譯,"armv7" 是 bionic 更動前的數據,而 "armv7-opt" 則是更動後的表現。很顯然發現,String 一項的改進大幅受到壓抑 (score = 1898:2140),致使兩者最終僅有些微的落差,可見 JNI 帶來 overhead 的著實不小。又,大部分應用程式的效能瓶頸往往在於圖形處理、系統資源的調度、檔案讀寫等 I/O 操作,所以現階段我們的想法是儘量調整 native 的部份,針對 ARM core 與 SoC 的特性作調整,並提出可行的輕量級 native method invocation 實做。

read on
Posted 張貼者: jserv 於 上午4:40 on | 0 意見
Filed under: , ,
 

強化 Android 的 shell

Android 預設的 shell 就是 /system/bin/sh 這個 process,移植自 NetBSD 早期的 sh 程式,原本功能算是完整,但被 Android 開發團隊移去相當多功能,致使在 shell 下的操作苦不堪言,只好透過 adb 作遠端指令的下達,但問題是,移植 Android 的平台在初期往往缺乏有效的連線機制,又需要作些調整與嘗試,實在很不方便。所以筆者就在 0xlab 最近釋出的 0xdroid 專案上,引入來自 Busybox 的 ash 實做,試著保持相近的 footprint 的前提下,提供更多的功能。

因此,我們有以下考量:

  • 必須動態連結到 bionic libc
  • 簡化 Busybox 的實做,修改 libbb 與對應的 applet
  • 保有 bash 相容模式, Line edit, history, readline 等 Busybox 特徵
稍早,0xlab 的成員 walkingice 就做了評估與實驗,讓整個 Busybox 得以動態連結到 bionic libc 並確保功能可運作,這部份有很多 hacking,暫時不談。現在這些更動已初步提交到 system/core repository。在 0xdroid 的 beagle-cupcake branch 下,相關的 ash 設定組態如下:
  • CONFIG_ASH_BASH_COMPAT
  • CONFIG_ASH_READ_NCHARS
  • CONFIG_ASH_READ_TIMEOUT
  • CONFIG_ASH_ALIAS
  • CONFIG_ASH_GETOPTS
  • CONFIG_ASH_BUILTIN_ECHO
  • CONFIG_ASH_OPTIMIZE_FOR_SIZE
  • CONFIG_ASH_EXPAND_PRMT
佔用的磁碟空間:
[build_host]$ ls -lh system/bin/{ash,sh}
87K 2009-08-13 02:24 system/bin/ash
98K 2009-08-13 01:15 system/bin/sh
佔用的記憶體空間:
[beagleboard] # ps
USER PID PPID VSIZE RSS WCHAN PC NAME
root 1 0 300 192 c00b2394 0000ca6c S /init
root 777 1 736 324 c0057648 afe0c3fc S /system/bin/sh
root 835 777 744 356 c0057648 afe0c3fc S /system/bin/ash
可以發現,新引入的 /system/bin/ash 佔用的磁碟與記憶體空間相似,但功能完整度卻大不相同,後者允許我們回顧歷史指令並編輯, 以及在 Embedded Linux 熟悉的操作環境。目前 ash 的移植還有很多調整改進的空間,不過算是堪用了,可在 init.rc 檔案中,將預設的 shell 指定為 /system/bin/ash。

read on
Posted 張貼者: jserv 於 上午3:33 on | 0 意見
Filed under: , ,
 

提供給 Beagleboard 的 Image Installer

這幾周,0xlab 的開發者都在準備新的 Android distribution,標的平台是 Beagleboard,可望在 COSCUP 到來前釋出,過程中順便寫了一個簡單易用的 Image Installer,可從 SD card 開機並將可運作的 Android system image 植入 Beagleboard 之上的 NAND flash,而不必依據繁瑣的流程,才能體驗我們的新創作。目前已有初步成果,可參見下圖:
已實做的特徵有:

  • 僅需要放置單一檔案 (uImage.bin) 到 VFAT 格式的 SD card 中,在 Beagleboard 插入 SD 開機進入 Image Installer,即有簡單俐落的 UI
  • 整個 Image Installer (kernel + busybox + file system + MTD tools + UI) 佔用不到 2Mb 的空間
  • 預設讀取 SD card 裡頭的 android_beagle.ubi 與 0xkernel-beagle.bin 兩個檔案,自動寫入 NAND flash,並設定必要的 u-boot 環境參數。放置 image 檔案的動作可在多數的作業系統平台下進行,舉凡 MS-Windows, GNU/Linux, Mac OS X 等等,只要支援 VFAT 與 SD/MMC 讀寫即可
貌似單純的 Image Installer 開發,卻折騰了好幾天,歸納有若干因素:
  • 準備在 Beagleboard/OMAP3 環境下可最小可啟動的 Linux image,需要考慮到 device driver 間的相依性,比方說若將 USB subsystem 完全移除的話,很可能無法正常開機。又,OMAP3 內建的 MFD (Multi-Function Device) 要注意到驅動順序的議題,不然功能無法正確運作
  • 要留意 TI OMAP3 / Beagleboard 啟動順序,即使 boot from SD,但 u-boot 與其 u-boot bootenv 很可能仍讀取自 NAND flash,這導致後續啟動的 Linux kernel 採用了預設值,致使 Image Installer 無法在預期的環境參數下啟動
  • ARM/Linux 啟動過程中,會試圖自一段特別的記憶體空間讀取 command line parameters,這空間稱為 ATAGS,係由 boot loader (以 Beagleboard 來說就是由 X-Loader 帶起的 u-boot) 填寫的記憶體內容,也就是所謂的 u-boot bootenv。但對 Image Installer 來說,雖然 u-boot 給予頗大的彈性,但也使得執行環境充滿不確定性
關於 ARM/Linux 的 ATAGS 實做程式碼可參考 arch/arm/boot/compressed/head.S 與 arch/arm/kernel/setup.c 兩個檔案,筆者做了簡單的 hack 以迴避:
--- android-omap.orig/arch/arm/kernel/setup.c 2009-08-08 18:40:30.000000000 +0800
+++ android-omap/arch/arm/kernel/setup.c 2009-08-08 18:43:09.000000000 +0800
@@ -613,7 +613,6 @@

static int __init parse_tag_cmdline(const struct tag *tag)
{
- strlcpy(default_command_line, tag->u.cmdline.cmdline, COMMAND_LINE_SIZE);
return 0;
}


由此可見,原本的動作是將 u-boot 對 ATAGS 寫入的資料寫入預設的 command line。至於安裝 Linux kernel image 與 root file system image 到 NAND flash 後,還得作 (NAND 裡頭的) u-boot bootenv 的編輯動作,這部份的工作原理可參考 Openmoko 開發的 Devirginator。喔,忘了說,這些惱人的限制,會在轉換到 Qi boot-loader 後迎刃而解 :)

read on
Posted 張貼者: jserv 於 下午9:45 on 2009年8月8日 星期六 | 1 意見
Filed under: , , ,
 

0xlab 在 COSCUP 2009 的議程分享

一年一度的「COSCUP / 開源人年會」即將於八月 15 與 16 兩日舉辦,今年的規模與議程深廣度再創新紀錄,依據公佈的議程大綱,今年大會有四個主題:
  • Android 和嵌入式系統
  • 雲端運算和 Web 技術
  • 開發者工具
  • 使用者桌面
0xlab 除了很榮幸能成為 COSCUP 贊助單位之外,也有四位開發者獲邀分享若干技術議程,以下摘錄 COSCUP 的演講摘要
講題:Android Wave Is Not Google Wave

講者:Chia-I Wu "olv" (0xlab)

摘要:

There is 3D acceleration on our laptops/netbooks. There is no reason that we cannot accelerate Android when it runs on the same devices. This talk is about 3D acceleration on Android. However, it will focus more on Mesa/DRI and focus less on Android, as the former is more open to our definitions.
講題: How Android Differs from GNU/Linux? And How can we FIX it?

講者: walkingice (0xlab)
摘要:
Android is indeed an open platform and large-scale open source project, which is amazing, but it excludes some well-known free and open source software such as glibc. This talk is about to share the experience about migrating from traditional GNU/Linux to Android. Also, 0xlab introduces some non-trivial modifications in order to leverage existing native Linux software into Android.
講題: Happy Build with OpenEmbedded
講者: tick (0xlab)

摘要:
Openembedded is a flexible and powerful autobuild system. It helps us porting different distributions to different hardwares without too much pain. I'd like to introduce the OpenEmbedded system via creating a tiny distribution and running it on a real embedded system. I will use beagleboard to demonstrate the image. If you have beagleboard, you can take that and play at the same time.
講題:Linux Virtualization Goes Mobile
講者:Jim Huang "jserv" (0xlab)

摘要:
Although the concept of virtualization has existed since the 1960s, the applications become mature and diverse recently. the term "hypervisor" is referred to the original goal: providing a virtualization layer that strictly isolates virtual machines from each other for security and reliability purposes, that meets the requirement of rich mobile devices nowadays. the talk covers running operating systems in isolated run-time environments on a single hardware platform, and what we can benefit from it: flexible system configurations, legal/contractual liability, secure designs, etc.
涵蓋 Android 3D、Android / Embedded Linux 開發,與 Linux virtualization 等等,屆時我們也會發布最近幾個月的成果,期待您的蒞臨指教,謝謝!

read on
Posted 張貼者: jserv 於 下午8:07 on 2009年7月28日 星期二 | 2 意見
Filed under: ,
 

Android/Beagle 效能改善簡記

以圖表展現前文「在 Android/OMAP 展現硬體加速的 OpenGL|ES 與影片播放」與「針對 ARMv7 優化的 Android」所提到的效能改善,可參見以下:

分析若干繪圖操作:

  • 302700 bytes memcpy
  • 512x512 unmodified texture, 512x512 blit
  • 512x512 unmodified texture, 512x512 blit (x2)
  • 512x512 modified texture, 512x512 blit
baseline 是原本 Android on Beagle 的移植,而 hardware-opt 則是運用 ARM NEON 指令集與硬體 OpenGL|ES 加速,基準 baseline 302700 bytes memcpy 時間為 1373 us,整體時間越短越佳。

read on
Posted 張貼者: jserv 於 上午11:13 on 2009年7月13日 星期一 | 0 意見
Filed under: , , ,
 

在 Android/OMAP 展現硬體加速的 OpenGL|ES 與影片播放

BeagleBoard0xlab 內部用來驗證 ARM 硬體的參考平台,這兩個月內,我們整合了若干無線通訊大廠的 WLAN/Bluetooth 晶片組,而 TI OMAP 353x SoC 的表現著實令人驚豔。初步對 ARMv7 做了優化後,我們進一步運用 OMAP DSP 與 Display Subsystem 的特性,下圖即是在 Android 上硬體加速的 OpenGL|ES 與影片播放,
透過 DVI-HDMI 到顯示器,呈現 1024x768 的解析度,圖上方可見 Android 的狀態資訊列,而最上層就是 video overlay,而下方是 OpenGL|ES 的繪圖區,被遮蔽的最底層則為 Android surface。TI OMAP 3 整體示意圖可參考下圖:
硬體支援三個 stacked overlays,其中 Video 2 和 Video 1 overlay 提供 RGB 及 YCbCr/YUV 的 color space,搭配 TI DSP 與 ARM NEON 加速指令集,可帶來相當順暢且華麗的展現。以下是稍早所作的 OpenGL|ES 與 HW video overlay 人機介面展示影片:

OpenGL|ES 由 PowerVR/Imagination Technologies 提供,搭配 OMAP2/3 嶄新的 DSS2 顯示架構,需要對 Linux kernel driver 作些調整,可參考筆者提供的套件與修改部份。當然這一切僅是基礎建設,銜接於 Android 及 ARM SoC 所需要的功夫仍相當多,期望不久的將來,我們的圖形處理達人會提出更多新玩意 :)

read on
Posted 張貼者: jserv 於 下午3:05 on 2009年7月8日 星期三 | 0 意見
Filed under: , ,
 

針對 ARMv7 優化的 Android

前文「升級 Android 內建 GNU Toolchain 到 gcc 4.4」提及使用更新的編譯器平台,現在追蹤的是 gcc 4.4/4.5,不排除引入 LLVM,這些準備都是為了允許施加更多優化、展現平台的特性,而在 Android 的 build system 也需要作一些更動,至少涵蓋以下:

  • 針對硬體平台的編譯參數
  • Dalvik machine-dependent interpreter implementation (mterp)
  • 針對硬體特徵優化的關鍵軟體,如 BlueZ 中處理音訊 Bluetooth low-complexity, subband codec (SBC) 的實做
當然優化是無止盡的,我們只求在合理的工程資源,能解決夠多的技術議題即可。筆者的參考修改可見 android-armv7.patch,其中做了以下調整:
  • 設定 gcc 編譯參數為 "-march=armv7-a -mtune=cortex-a8 -mfpu=neon",適用於 BeagleBoard (TI OMAP 353x) 平台
  • 額外啟動 gcc 的 Auto-vectorization 優化策略
  • 以 ARM NEON 指令集優化 SBC 的執行效能
前期我們還是著重於泛 ARMv7 平台的優化技術,再來就是針對 SoC 平台的 DSP 與特性去作進一步處理。為了證明以上的修改發揮作用,可檢視 libjpeg 是否自動的做了 vectorized,也就是看看有無 ARM NEON 指令集的生成:
# ./prebuilt/linux-x86/toolchain/arm-eabi-4.4.0/bin/arm-eabi-objdump -d \
out/target/product/generic/obj/STATIC_LIBRARIES/libjpeg_intermediates/jdmerge.o | egrep "v[add|mov]"
1d4: f2c09012 vmov.i32 d25, #2 ; 0x00000002
1d8: f3c01210 vmov.i32 d17, #32768 ; 0x00008000
200: f26048a9 vadd.i32 d20, d16, d25
204: f22069b8 vmul.i32 d6, d16, d24
208: f26438a9 vadd.i32 d19, d20, d25
20c: f2266821 vadd.i32 d6, d6, d17
至於 ARM NEON 指令集,這裡不贅述,可參考 ARM 官方文獻 NEON Technology

read on
Posted 張貼者: jserv 於 上午10:41 on 2009年7月1日 星期三 | 1 意見
Filed under: , , ,
 

簡報: Power Management from Linux Kernel to Android

上週五 (June 19),Matt 跟我分享 Android 之上 Power Management 的背景概念、實做,以及可改進的方向,而論及 Android 的系統架構設計時,不免得先談談 Linux PM,期待這份簡報對進行系統移植與客製化的同好有助益:

授權方式採用 Creative Commons S-A 3.0,不完善與謬誤處,請多指教,謝謝!

read on
Posted 張貼者: jserv 於 上午4:36 on 2009年6月22日 星期一 | 1 意見
Filed under: , ,
 

升級 Android 內建 GNU Toolchain 到 gcc 4.4

GNU GCC 4.4 已於 Apr 21, 2009 正式釋出,伴隨眾多改進、修正,與硬體平台改善,詳情可見"GCC 4.4 Release Series Changes, New Features, and Fixes",不過 Android repository 裡頭的 prebuilt GNU Toolchain 仍停留在 gcc-4.2.1 (Release date: Jul 18, 2007),總是有些遺憾,且讓我們動手改變。

EMBINUX™ Lab 提供一份 prebuilt GNU Toolchain for Android,參考其 git 的更動,可建立一套基於 gcc-4.4 與 binutils-2.19.1 的 toolchain,筆者準備打包好的套件: toolchain-arm-eabi-4_4_0.tar.bz2。另外,因為 gcc-4.4 對於 C/C++ 語意更加嚴格,像是應用程式對 va_list 的使用就需要調整,筆者將這些小修改整理為 migrate-gcc44.patch。以下是簡要的升級方式:

# cd mydroid
# cd prebuilt/linux-x86/toolchain
# tar jxvf toolchain-arm-eabi-4_4_0.tar.bz2
# cd ../../..
# patch -p1 < migrate-gcc44.patch
重新編譯與建構 Android 即可。需要更動的部份,列出作參考:
# diffstat migrate-gcc44.patch
core/combo/linux-arm.mk | 2 +-
dist/sqlite3.h | 2 +-
envsetup.sh | 2 +-
pdk/ndk/samples/sample/Makefile.lib | 2 +-
4 files changed, 4 insertions(+), 4 deletions(-)

read on
Posted 張貼者: jserv 於 下午6:04 on 2009年6月18日 星期四 | 1 意見
Filed under: ,
 

改善 Android 中 memcpy 效能

在 Android 內部實做中,有許多細節涉及大量的 memcpy() 操作,比方說將一塊使用者定義的繪圖區域傳遞給 SurfaceFlinger 管理的過程,由於得先轉換成 texture,再對應為 Surface,之間至少需要三次 memcpy。由於 BeagleBoard (TI OMAP3) 透過 HDMI 輸出 (max: 1280x1024),居中涉及大量的繪圖操作,意味著 memcpy() 頻繁被呼叫著,對整體效能有顯著的影響,於是筆者花了一些時間分析。

Android 的 libc 實做 -- bionic -- 已包含針對 ARMv5 優化過的 memcpy(),詳情可參考 libc/arch-arm/bionic/memcpy.S,而 GNU Toolchain (glibc) 中,其實也有一份針對 ARMv5 優化過的 memcpy() 實做,也利用到 ARMv5 的 data prefetch 指令。既然我們採用 ARMv7 架構的 BeagleBoard,何不使用其引入的 NEON SIMD 加速指令集呢?以下就是在 BeagleBoard 所作的 benchmark:

數據如下:

  • glibc-armv5 : 181884276 B/s
  • bionic-armv5 : 225881095 B/s
  • armv7 : 269294302 B/s
參考的 ARM NEON 優化 memcpy() 實做如下: (arm-neon-memcpy.S from Måns Rullgård )
  1. .fpu neon
  2. .text

  3. .global memcpy_neon

  4. .func memcpy_neon
  5. memcpy_neon:
  6. push {r4-r11}
  7. mov r3, r0
  8. 1: subs r2, r2, #128
  9. pld [r1, #64]
  10. pld [r1, #256]
  11. pld [r1, #320]
  12. ldm r1!, {r4-r11}
  13. vld1.64 {d0-d3}, [r1,:128]!
  14. vld1.64 {d4-d7}, [r1,:128]!
  15. vld1.64 {d16-d19}, [r1,:128]!
  16. stm r3!, {r4-r11}
  17. vst1.64 {d0-d3}, [r3,:128]!
  18. vst1.64 {d4-d7}, [r3,:128]!
  19. vst1.64 {d16-d19}, [r3,:128]!
  20. bgt 1b
  21. pop {r4-r11}
  22. bx lr
  23. .endfunc
至於 SurfaceFlinger 的操作仍有優化的空間,稍後再討論。

read on
Posted 張貼者: jserv 於 下午2:34 on | 1 意見
Filed under: , , ,
 

Android Dalvik VM vs. Java VM

Google Android 開發團隊為了技術自主、迴避 Java 商標爭議等考量,建構了嶄新的 Dalvik Virtual Machine,骨子裡頭仍支援 Java 程式語言,但 Dalvik VM 設計稍異於典型 JVM,網路上已有豐富的比較,本文就不贅述,筆者想探討的,則是日本 eFlow 公司最近提出的 'Android™'s Dalvik VM on "Mobile Java"',目標就是讓原本的 Java 執行平台 (主要是 Java ME),得以運作針對 Android Dalvik VM 設計的應用程式。日前該專案已開放原始程式碼,主體依據 GNU GPLv2,以下是相關資訊:

目前的進度來說 (svn r22),支援以下功能:
至於是否能達到 eFlow 公司 CEO -- Koichi Makabe 所預期的效益:
"We believe this implementation will particularly benefit manufacturers currently developing Android-powered devices, with a number of which we are cooperating to port the Dalvik VM to their specific hardware and software architectures. By making this implementation available today as open source, and by accelerating our porting and development efforts, we have the firm intention to make a significant contribution to the broader Android community."
這裡無從得知,不過,該專案四月底時,一併將 dalvikvm_benchmark 釋出,伴隨內部的效能分析數據,非常有意思。從裡頭的資料來看,標的硬體平台有兩個:
前者無疑就是用來比較的基準,硬體是 Qualcomm 平台,軟體組態當然是跑 Dalvik VM,運作時脈為 528 MHz。後者就相當有意思,P905i 是日本 NTT 電信的第三代手機平台,以豐富的多媒體與超長待機時間著稱,硬體採用 Panasonic UniPhier 家族,運作時脈達 500MHz,軟體方面,則內建 JBlend 這個商業 Java ME CLDC/MIDP 執行環境。儘管軟硬體組態均大相逕庭,不過研究 android-dalvik-vm-on-java 提供的內部的效能分析數據,多少有參考的價值。筆者整理為以下圖表:
綠色部份 (靠右側者) 為 Google Dev Phone 1,紅色 (靠左側者) 則是 P905i,分數越高者越佳。在同一份 benchmark 測試方式來看,兩者有極為顯著的落差,整體表現數據為:
數字背後的意義則是,Dalvik VM 進一步優化的空間仍相當大,至於如何在 ARM11 平台,透過若干進階的技巧 (JIT, register allocation, ...),發揮 Dalvik 這個 register-based VM 的效能,是不少研究人員關心的議題。

read on
Posted 張貼者: jserv 於 下午10:04 on 2009年5月10日 星期日 | 2 意見
Filed under: , , , ,
 

Android 上的原生 OpenGL/ES

olv 日前在「一千零一夜之 Android Binder」一文提及:

surface manager 可以準備一塊 surface,把 surface 的 fd (一塊 ashmem 記憶體) 傳給一個 app,讓 app 可以在上面作畫。有了這層理解,我們對 android 可以有更自由的發揮,例如,可以不改一行 cairo 的程式碼,就利用 cairo 與 c++ 寫出一個會動的時鐘
而 Surface manager 顧名思義,就是管理邏輯上眾多的 surface,其底層對應於 OpenGL|ES 的實做。透過 surface 的處理,我們可讓像 fdclock 這樣原生 (native) 的 C 語言程式,透過同樣在 GNU/Linux 上原生的 Cairo 函式庫,無痛的顯示處理。這實在很吸引人,畢竟若能在 Android 平台充分重用 GNU/Linux 既有的軟體功能,會是多麼有趣的事。且讓我們思考是否能在 Android 上撰寫 C 語言的 OpenGL/ES 應用程式。

Android 已提供初步的 OpenGL/ES 封裝,實做則是透過 agl (Android OpenGL) 底層的 PixelFlinger 與 GPU。關於 Java 部份的 OpenGL APIs 操作,可參閱原始程式碼 frameworks/base/opengl/java/android/opengl/GLSurfaceView.java ,不過現在只看 C 程式的部份。動態連結函式庫必須連結到以下三者:
  • libEGL : OpenGL/ES APIs
  • libGLESv1_CM : Reference implementation
  • libui : Android UI framework (native)
準備好我們的程式碼之後,其建構過程如下:
$ . build/envsetup.sh
$ cd angeles-test/
$ mm
make: Entering directory `/home/jserv/Myth/mydroid'
target arm C: angeles-test <= /home/jserv/Myth/mydroid/angeles-test/demo.c
...
參考的螢幕顯示如下:

不過,在模擬器顯示的狀況會比實體遜色頗多,可見到相當嚴重的重繪動作,但基本上是可用的。

read on
Posted 張貼者: jserv 於 下午5:26 on | 0 意見
Filed under: , ,
 

整合 GStreamer 到 Android

Thinker 在「GStreamer 和 OpenMAX IL 的比較」一文提到:

GStreamer 是知名的 open source multimedia framework,相當於 Windows 下的 DirectShow 。而 OpenMAX IL 則是多家知名廠商參與制定的標準,其功能和 GStreamer 也有些類似。目前已有一些 multimedia framework 開始支援 OpenMAX IL,以使用 OpenMAX IL 相容的 component 。 OpenMAX IL 是一個 codec 的標準介面,實作該介面的 codec 可以被任何 OpenMAX IL client 所使用。目前 Android 使用的 opencore 所支援的 codec 實在很少,如果可以透過實作 OpenMAX IL 的 wrapper ,讓 FFmpeg 之類的 multimedia framework 所提供的 codec 能當成 OpenMAX IL 的 component 載入,那麼 opencore 瞬間就多出許多 codec 可以使用。
這個想法已經被 Prajnashi S 初步實現,雖然層面不同,但還是有很大的參考價值。下午將之前的程式碼升級到 Android cupcake (1.5 Release),做了一些微調,在 target 上運作起來,先看看有哪些 plugin:
# gst-inspect-0.10
audiotestsrc: audiotestsrc: Audio test source
videotestsrc: videotestsrc: Video test source
omx: omx_dummy: OpenMAX IL dummy element
omx: omx_mpeg4dec: OpenMAX IL MPEG-4 video decoder
omx: omx_h263dec: OpenMAX IL H.263 video decoder
omx: omx_h264dec: OpenMAX IL H.264 video decoder
omx: omx_mp3dec: OpenMAX IL MP3 audio decoder
omx: omx_amrnbdec: OpenMAX IL AMR-NB audio decoder
omx: omx_amrwbdec: OpenMAX IL AMR-WB audio decoder
omx: omx_aacdec: OpenMAX IL AAC audio decoder
audioflingersink: audioflingersink: Audio Sink (AudioFlinger)
videoflip: videoflip: Video flipper
quicktime: qtdemux: QuickTime demuxer
coreelements: capsfilter: CapsFilter
coreelements: fakesrc: Fake Source
coreelements: fakesink: Fake Sink
coreelements: fdsrc: Filedescriptor Source
coreelements: fdsink: Filedescriptor Sink
coreelements: filesrc: File Source
coreelements: identity: Identity
coreelements: queue: Queue
coreelements: filesink: File Sink
coreelements: tee: Tee pipe fitting
coreelements: typefind: TypeFind
coreelements: multiqueue: MultiQueue
ffmpegcolorspace: ffmpegcolorspace: FFMPEG Colorspace converter
surfaceflingersink: surfaceflingersink: android's surface flinger sink
coreindexers: memindex: A index that stores entries in memory
videoscale: videoscale: Video scaler
staticelements: bin: Generic bin
staticelements: pipeline: Pipeline object

Total count: 12 plugins, 31 features
這表示,透過 GStreamer,Android 瞬間多了許多高品質的 plugin 與外加功能,也就能以 FFmpeg 或既有的 gst-plugins 來處理各式的多媒體資料。現在 video 的處理,可透過 Surface Flinger sink 來操作,測試方式:
# gst-launch-0.10 videotestsrc ! surfaceflingersink
以下是對應的螢幕輸出:

稍後,我們再來探討整合的議題。

read on
Posted 張貼者: jserv 於 下午5:25 on 2009年4月29日 星期三 | 1 意見
Filed under: , ,
 

0xlab 開幕!

愛因斯坦說過:「對一個人來說,所斯望的不是別的,而僅僅是他能全力以赴和獻身於一種美好事業」,今天,台灣有一小群工程背景的朋友,憑恃著如此的信念,打算為台灣的資訊產業,作些事情,所以成立 0xlab。愛因斯坦又說:「信念最好能由經驗和明晰的思想來支持」,我們的成員則根基於過去參與自由軟體 / 開放原始碼專案的協同開發經驗,以及對追求理想和真善美的堅持,透過 0xlab 這個嶄新的嘗試,將原本散落各地的開發資源,集中起來一同打拼,目前為止的成員有 8 位,依序是 Erin, Jeremy, John, Jserv, Julian, Olv, Thinker, Tick。每個人各有其專擅的領域,我們希望以團隊的優勢提供完整戰力,為軟體界做出些許貢獻,以技術的方式來愛台灣!

個人一直認為,工程師若要愛台灣,最好的方式,就是強化本職學能,無論是軟硬體技術,使其累積、成長,進而提升到更高的層次。今天,2009 年 4 月 27 號,是 0xlab 的誕生日,專注於推動硬體廠商與開放軟體社群的聯繫,成為軟硬體整合方案提供者,讓更多基於開放軟體的裝置走入日常生活。

read on
Posted 張貼者: jserv 於 上午7:55 on 2009年4月27日 星期一 | 0 意見
Filed under: ,
 

當 Compiler 遇上 Mobile

過去我們很難聯想進階的編譯器 (compiler) 技術到底與移動平台何涉,但隨著基礎建設的突破,我們就該有不同的思維。

從1960 年代發展至今,編譯器技術已是電腦科學最成熟的基礎之一,不斷地成長與蛻變,而透過 open source,GNU GCC 與 LLVM (Low Level Virtual Machine) 計畫獲得空前的成功,累積了驚人的編譯器技術。儘管 parser 仍是 compiler 的關鍵技術,但今日,我們會著重於打通任督二脈的技術展現,過去耳熟能詳卻貌似獨立的項目,比方說 virtual machine, binary translator, JIT compiler, HotSpot JVM, 等等,如今好似整合了金庸書中的武功精髓、淬湅出武術菁華,形成一套獨到的武功系統,透過 LLVM 一類的整合性技術而一瀉千里。

幾年前,知名的遊戲設計公司 id Software 在該公司靈魂人物 John Carmack 的主導下,將 Doom (毀滅戰士) 核心的遊戲引擎以 GNU GPL 開放授權釋出,自此開啟廣泛的平台移植與功能強化的的濫觴。早期的 Doom GPL 程式碼被 Sam Lantinga 移植到 SDL 圖形函式庫,藉由 SDL 優異的可攜性,眾多硬體環境得以運行 Doom 遊戲,儘管遊戲的資料檔並非自由軟體。另一方面,現在最火熱的移動平台,就屬 Google Android 開放源碼平台,為了迴避 Sun Microsystems 對 Java 的控制權 (logo + patent),該平台整合大部分 Apache Harmony 專案的成果,建立了一套貌似 Java 語言但執行環境大異於 Java 的嶄新虛擬機器 -- Dalvik,將原本 stack-based VM (JVM) 轉換為 register-based VM (Dalvik VM),而無論這裡頭有多少玄機,就 Android 的程式設計來說,Java 是唯一可用的程式語言,要不得搭配 Android framework / class library,不然就是透過 JNI 去呼叫 C/C++ 撰寫的動態函式庫。作為一個「慣 C 魔人」, 筆者反覆思考,是否能將以 C 語言搭配 SDL 函式庫撰寫的 Doom,透過編譯器轉換為 Android 平台可運作的 Dalvik bytecode 呢?此舉不僅讓 C/C++ 程式跨平台執行,還為移動平台提供了新的附加價值,於是,筆者就開始一系列的 hacking,現在有初步的成果,日前已發表於 OSDC.tw 2009 的「窮得只剩下 Compiler」議程中,請參考以下螢幕快照:
這可不是紙老虎或單純貼圖,電動玩具當然是設計來玩的:
詳細的資訊可參閱發表於 OSDC.tw 的議程簡報:

View more presentations from Jim Huang.
筆者同事 luse 嘗言:「現在是一個充滿編譯器的世界,身為一個工程師,每次聽到編譯器技術,覺得深不可測 (或是腦海忽然浮現起自動機的回憶) 而輕言放棄,實著可惜」。許多人印象中艱澀的 (dynamic) Compiler 技術,其實廣泛應用於我們電腦資訊產業中,以「到處都是 Compiler」來闡述現實,一點也不為過。如此的案例多如牛毛,比方說,現在 Web 2.0 與 Mobile web browser 正火熱,為了要能改善 Web 應用程式的效能,Google 與 Apple 兩家公司的工程團隊,各自推出 V8 與 SquirrelFish Extreme 等 Just-In-Time compiler for JavaScript,而 Mozilla Foundation 更是將高速的 JavaScript 引擎當作 Mozilla 2 的重要賣點,知名的自由軟體開發者 Jim Blandy 甚至離開專業 GNU Toolchain 開發公司 CodeSourcery,加入 Mozilla Corporation,就為了致力開發 ActionMonkey (整合 Mozilla 原有 SpiderMonkey 與 Adobe 貢獻的 Tamarin)。自此,這個在瀏覽器平台的戰役,從桌面系統延續到手機,又將從手機移轉到各種不同的資訊裝置上。

而,撇開 JavaScript 執行引擎不論,實際上,連 Firefox/Mozilla 底層的向量繪圖函式庫 Cairo,也透過 JIT compiler 技術,去提昇整體繪圖的效能與使用者體驗。日前,Dan Amelang 揭露他的開發成果,可參見郵件論壇的訊息 "JIT for pixman"。pixman 是提供給 X Window System 與 Cairo 使用的 pixel-manipulation 函式庫,顧名思義,就是處理 image compositing 與 trapezoid rasterization 等操作,而在 Dan Amelang 的論文 "Jitblt: Efficient Run-time Code Generation for Digital Compositing" 給予令人振奮的突破,無疑是個極佳的突破點,我們也可預見 (dynamic) compiler 技術在更多資訊領域的廣泛應用。

當編譯器技術走入新的層次時,就需要更強大且多元的 Toolkit,LLVM 專案的出現,在整個電腦技術典範移轉 (paradigm shift) 的衝擊下,以嶄新編譯器架構、自由軟體協同開發模式,給予我們突破限制的可能性,顯然,我們可確定 LLVM 應用於 Android 應用程式開發,僅是一個牛刀小試,好戲才要登場呢。

read on
Posted 張貼者: jserv 於 上午3:48 on 2009年4月26日 星期日 | 0 意見
Filed under: , , , ,
 
Developer at 0xlab.