Linux System Kernel Application Survey report Stack-based or Register-based Virtual Machine
Wen-Cheng Tsai R97921035
Graduate Institute of Electrical Engineering March 31, 2010
1. Introduction
Virtual machine(VM)是一個以軟體的方式實做出來的機器,它並不是一個 實體,但是卻可以像一個真實的機器般執行程式。在 2007 年 11 月 Google 公 布了一個以 Linux 為核心的行動電話系統平台 -『Android』,除了以 Linux 為 核心之外,在 middleware 的部分 Google Android 開發團隊為了技術自主、迴 避 Java 商標爭議等考量,建構了嶄新的Dalvik Virtual Machine,VM 的設計架 構為 register-based 有別於典型 Java VM 的 Stack-based 架構,這次 survey 的 主題將探討兩者之間的差異性。
2. Stack-based machine
Stack-based 或 register-based 都是一種為了方便電腦運算所開發出來的 model,這種電腦的 memory 由一個或多個 stack 組成,而這種電腦適用於 0-operands 的 instruction set,因為從 memory fetch 資料的動作都可以由 stack push/pop 來完成,也就是 always 讀取 memory 最上層的資料。這種 model 的好處是 instruction 的 size 都非常精簡。
3. Register-based machine
Register-based 適用於 2-operands 或 3-operands 的 instruction set,它不 同於 Stack-based 的地方在於資料是從 registers fetch 而不是 stack,而每個 register 有它自己獨特的 address,這種性質讓 CPU 可以直接對 registers 存取 資料,而不用藉由頻繁的 push/pop 動作來存取 stacks。
4. Stack vs. registers
在 VM 的 interpreter 執行一個 VM instruction,可分成三個部分來比較。
Dispatching the instruction
Instruction dispatching 包括從記憶體讀取指令到跳到相對應的程 式片段,以 Table1 表格為例,原始碼為 a = b + c,經過interpreter將原始 碼轉換成 stack /register-based 的 instruction,stack-based 需要 4 次 Instruction dispatching,而 register-based 只需要一次,所以register-based 的 instruction 可以大大的減少 Instruction dispatching 的 cost。
Original code Stack-based Register-based a = b + c ILOAD c
ILOAD b IADD ISTORE a
IADD a b c
Accessing the operands
Register-based 的 會將 operands 儲存在不同 registers, 相對地 Stack-based 會將每次要運算的 operands 先存到 stack,要運算時就會 pop 出 來 交 給 CPU 執 行 , 而 通 常 Register-based 的 code size 會 大 於 Stack-based 的 code size,因為 Stack-based 只要記錄放置 operands 與 stack point 的相對位置並使用 push 和 pop 的指令,而 Register-based 必 須明確記住 operands 放在哪個 register。另外,Register-based 的 code 也會因此用到較多的 memory,這也是為什麼 Stack-based 的架構會如此 受到 VM 的喜愛。
Performing the computation
在運算方面,Stack-based 的架構無法重複使用一些常用的 constants,
相對地,若使用 Register-based 架構就可以解決這些問題,因為一旦將 value load 進 register 之後,便可以重複使用直到 method 結束。另外,
Stack-based VM 常常會有頻繁的 memory push/pop,使用 Register-based VM 可以利用一些最佳化的技術,減少不必要的 memory load。如:
Forward/Backward Copy Propagation
Forward/Backward Copy Propagation 主要是用來消除一些 不必要的 move 指令,它的原理是看前後幾個指令有沒有
Table 1: Original code translation
dependency 的關係,例如下面的 4 行 source code
因為 第 1,2 行的 move 明顯是多餘的,因為不需要將 r1、r2 的 資料搬到 r10、r11,而第 4 行的 move 也是同樣的意思,經過 Forward/Backward Copy Propagation 的步驟後可以簡化成下面 的程式碼
Constant optimization
在 stack-based VM 無法將常用到的 constant 保存在 stack 中,但是 register-based VM 則可以預先 scan source code,並 在程式執行一開始將一些可能會常用到的 constant 預先存放 在某些 registers 中,這種作法可以減少多餘的 constant 的 load。
5. Evaluation
從上述看來 Register-based 的 code size 會大於 Stack-based,因此需要花 費較多時間從 memory fetch instruction。[1]的結果顯示,同一段 source code 分別轉換為 stack-based instruction 和 register-based instruction 來比較,平均 來說 register-based code size 比 stack-based 增加 25.05%的 size。
相反的,處理同樣的工作,Register-based VM 只要花較少的 instructions,
Stack-based VM 則需要花較多的 instructions。從數據上來看,Register-based 的 instruction 減少了 43.47%的 move 指令和 6.95% 的 constant。
目前看來各有好壞,到底哪一種在 execution time 較有效率呢?根據[1]
對不同的 13 個 method 測試的結果,平均 Stack-based 轉換成 Register-based 時,增加的 code size 花費在 load 的 cost 與消去多餘 instruction 的 cost 比例 大概是 1.07%,這說明了消去多餘 instruction 的 cost 遠遠大於增加的 load cost,
因此 register-based machine 在執行程式上會更有效率。
1. move r10, r1 2. move r11, r2 3. iadd r10, r10, r11 4. move r3, r10
3. iadd r3, r1, r2
6. Conclusion
長久以來的一直存在的問題,到底 Stack-based or Register-based 的 VM 執行程式可以更有效率,明顯的,Register-based 的架構將會更有效率,因 為和 Stack-based 相比,Register-based 的架構可以透過許多最佳化的技術有 效減少許多不必要的 instruction。Google 除了考量到 Register-based VM 易於 最佳化的特性,最重要的如意算盤是 Dalvik 並非 Java ME 的實作,因此沒有 Java ME 授權的問題。
7. Reference
[1] Shi, Yunhe; Gregg, David; Beatty, Andrew; Ertl, M. Anton (2005-06-11).
“Machine Showdown: Stack Versus Registers” Retrieved 2009-12-22.
http://www.usenix.org/events/vee05/full_papers/p153-yunhe.pdf
[2] Android Dalvik VM vs. Java VM
http://jserv.blogspot.com/2009/05/android-dalvik-vm-vs-java-vm.html [3] Google 文件:程本中介紹 Android: Dalvik VM Internals
http://docs.google.com/Present?docid=dfqs8fqs_4379243wxzk