999精品在线视频,手机成人午夜在线视频,久久不卡国产精品无码,中日无码在线观看,成人av手机在线观看,日韩精品亚洲一区中文字幕,亚洲av无码人妻,四虎国产在线观看 ?

基于國產自主CPU 的SEP0611 平臺中Dalvik 虛擬機的移植和優化

2012-12-22 05:59:36昊,張
電子器件 2012年3期
關鍵詞:優化方法

吳 昊,張 哲

(東南大學國家專用集成電路系統工程技術研究中心,南京210096)

Google 于2008 年發布的Android 系統,因其開放源碼完全免費等特性[1],在嵌入式領域[2]異軍突起,吸引了大量的方案解決公司和設備制造廠商,如今占據智能手機領域的半壁江山。但官方原生的Android 系統并不支持所有CPU 架構,其中Dalvik虛擬機就是一方面的體現。雖然目前絕大部分的Android 產品是基于ARM 架構,但是非ARM 架構陣營正努力向Android 靠齊。

為了使非官方支持的架構平臺運行Android 系統,需要對Android 的多個方面進行移植與修改。其中包括最基本的編譯工具鏈的支持、Android 系統的整個編譯系統的修改、bionic 庫的移植和Dalvik虛擬機的移植。

本文通過分析研究ARM 架構Android 系統Dalvik 虛擬機[3],為基于自主內核Unity 的國產SoC SEP0611 的Dalvik 虛擬機的移植和優化起到指示性作用。第2 節分析了Dalvik 虛擬機的硬件平臺相關性和Java 平臺無關性,定位Dalvik 虛擬機移植的重點和關鍵。第3 節介紹了Dalvik 虛擬機在SEP0611國產自主SoC 上的移植,然后重點分析以ARM 架構為代表本地方法調用橋。第4 節介紹了Dalvik 虛擬機在SEP0611 國產自主SoC 上的優化,并且對Dalvik 虛擬機優化的幾個方向進行了分析與研究。

1 Dalvik 虛擬機平臺

Dalvik 虛擬機運行的是Java 程序,所以Dalvik 虛擬機有Java 虛擬機的遺傳基因,我們暫且認為Dalvik虛擬機是經過裁剪優化過的Java 虛擬機。Dalvik 虛擬機是否屬于Java 虛擬機只是理解層面上的差異:若把Java 虛擬機理解成運行Java 程序的虛擬機,那Dalvik 虛擬機就屬于Java 虛擬機的范疇[4];若Java虛擬機是指運行特定格式指令集或包含特定技術專利的虛擬機,則Dalvik 虛擬機則不屬于Java 虛擬機。

1.1 Java 的平臺無關性

Java 語言有一個眾所周知的強大特性——write once,run anywhere[5]。實現Java 語言平臺無關性的關鍵就是各種不同平臺的虛擬機與所有平臺都使用統一的存儲格式——Class 字節碼,即字節碼是構成平臺無關性的基石,虛擬機則是字節碼實現的載體。

同時,Java 編譯語言本身體現了平臺無關性:其基本數據類型的值域和行為都是由Java 語言本身定義,而與目標平臺無關。如基本數據類型int 都是用32 bit 二進制補碼表示。同樣的,Java 虛擬機內部和Class 文件中都是一致的。

至此為止,本文分析平臺無相性的都是從語言本身或體系結構的角度出發。從這一角度分析影響平臺相關性的因素包括:Java 平臺的部署;Java 平臺的版本;本地方法的使用;非標準的運行庫;對虛擬機的依賴;對用戶界面的依賴。

1.2 虛擬機與硬件平臺的相關性

本文所關心的平臺相關性并非上文所述,而是狹義的指虛擬機本身的實現在編譯之前與特定目標架構的相關性,這也是Java 語言聲稱的平臺無關性必然帶來的的問題——虛擬機是平臺相關的。虛擬機屏蔽了Java 語言的平臺相關性,代價就是在每一個平臺上實現一種虛擬機。

當然,本文所述的Java 程序有別于大家熟知的Java 程序,因為它基于Dex 字節碼。不同平臺的Java 虛擬機都能運行Java 編譯器編譯好的程序,是因為這些Java 虛擬機都運行Class 字節碼。同樣的,Dalvik 虛擬機在不同平臺上實現統一的Dalvik字節碼——Dex 字節碼,就能現實Dalvik 虛擬機的平臺無關性。

2 Dalvik 虛擬機的移植

Dalvik 虛擬機中Dex 字節碼成為了Android 應用程序平臺無關性的基石,但真正意義上的應用程序的跨平臺運行的基礎確屬Dalvik 虛擬機。Dalvik虛擬本身架構是用C 語言實現,而且Java 應用程序中可以帶本地庫,這兩種方法都是Java 程序中JNI(Java Native Interface)機制的一個體現。通過分析研究發現,JNI 機制中的本地方法調用橋環節正是基于自主內核Unity 的國產SoC 的Dalvik 虛擬機移植的關鍵。

2.1 基于自主內核Unity 的國產SoC 介紹

Tiger 是定位于移動多媒體、衛星導航產品的高性能應用處理器,采用TSMC65nm 工藝,封裝TFBGA400,17 cm×17 cm,主要有以下特性:

(1)UNITY-2 內核,主頻最高800 MHz;

(2)多總線架構;

(3)支持DDR3/DDR2/SRAM/NOR/NAND 存儲器接口;

(4)支持H. 264/MPEG4/DivX/VC1/RV 等主流視頻格式的1080P 解碼;

(5)支持外接AUDIO CODEC 芯片實現音頻輸入輸出;

(6)支持外接HDMI 芯片實現HDMI 視頻輸出;

(7)支持24 bit 色LCD 輸出,可支持4 層Overlay;

(8)內嵌USB OTG 2.0 控制器,支持外接PHY實現USB 2.0 傳輸;

(9)支持SDIO 接口和SDHC 存儲卡;

(10)高速SPI/UART/I2C 等串行接口;

(11)支持年月日時分秒實時時鐘;

(12)支持GPS 定位;

(13)內嵌電源管理,可動態調整頻率;

2.2 虛擬機中的JNI 機制

從Java1.1 開始,JNI 標準成為Java 平臺的一部分,它允許Java 代碼和用其他語言編寫的代碼進行交互。使用JNI,需要在使用本地方法的Java源碼中聲明本地方法,然后在C 或C++中實現該本地方法,最后將本地方法注冊到系統中。聲明時,必須使用Native 關鍵字,本地方法的實現使用的數據類型也應該遵循JNI 框架,將本地方法注冊到系統是通過調用JNIRegisterNativeMethods 實現,該函數需要傳入所有本地方法的一個集合——本地方法列表。本地方法列表中的每一項都是一個結構體,這個結構體正是JNI 的核心:JNINative-Method。

typedef struct{

const char* name; /* JNI 函數的名稱* /

const char* signature;/* 描述JNI 函數的參數和返回值* /

void* fnPtr; /* JNI 函數對應的C 語言的函數指針* /

}JNINativeMethod;

其中,Dalvik 虛擬機比較關心的部分是該結構體的第2 項Signature。因為Signature 中包含了JNI函數的參數和返回值類型,這指明了Java 調用本地方法時參數和返回值的類型,然后虛擬機根據架構的傳參規則及Signature 解析的結果,完成參數從Java 到C/.C++的傳遞。

2.3 本地方法調用橋的實現

上面§2.2 簡單介紹了JNI 機制,現在來分析JNI 中與特定平臺相關的部分——本地方法調用橋。這個部分是移植Dalvik 虛擬機的關鍵部分,主要體現在兩個方面:一是特定架構平臺下數據類型的對齊要求;二是特定架構下函數調用傳參規則。事實上,在特定平臺上實現這兩個部分就算是完成了Dalvik 機的移植。剩下的其它工作主要是優化和測試了。

從分析ARM 體系架構的實現開始,可以發現ARM 架構遵循ARM EABI 規范[6],入口棧地址是8 bit 對齊、64 bit 數據(包括long long 和double)在棧中要求8 bit 對齊。因此在解析Signature 時,遇到‘D’和‘J’,應該判斷在棧中存取當前數據時是否是8 bit 齊。若不是則需要用預留或插入一個32 bit 空白數據,并使用相對應的位來標記該32 bit 空白數據。

為了實現該特性,先在HintsEABI. c 的文件中提前解析好Signature,把記錄好的信息存儲在一個32 bit 長的數據jniHints 中,該jniHints 作為函數的返回值返回,被存儲到jniArgInfo 中。而另一個函文件CallEABI. S 中的函數dvmPlatformInvoke 的第三個參數則是jniArgInfo,函數dvmPlatformInvoke 的功能是:按照函數調用傳參規則實現函數函數的傳遞。這樣,通過HintsEABI.c 和CallEABI.S 的配合工作,完成了JNI 本地方法調用時函數的傳遞。

HintsEABI.c 中生成的jniHints 的主要功能是:在CallEABI.S 中完成本地方法調用傳遞參數時需要為用棧傳遞的部分參數開辟多大的棧空間。當然開辟靜態的一個大的空間能滿足參數的傳遞,但這樣的實現會浪費大量的內存,這對內存相對較小的嵌入式設備來說無疑是致使的。所以使用這樣一個機制,開辟一個大小剛剛好的棧來完成參數傳遞是一種很巧妙的方法。

由于ARM 中long long 和double 在棧中要求8字節對齊的特性,需要對生成的jniHints 作一番特殊的處理,jniHints 存儲了jniArgInfo 的低28 bit 和第31 bit:

//dvmPlatformInvokeHints(proto)返回值為jniHints

hints=dvmPlatformInvokeHints(proto);

if(hints & DALVIK_JNI_NO_ARG_INFO){

jniArgInfo |=DALVIK_JNI_NO_ARG_INFO;

}else {

assert((hints & DALVIK_JNI_RETURN_MASK)= =0);jniArgInfo |=hints;

下面來詳細介紹ARM 架構下jniArgInfo 32 bit數據每一位的構成:

SRRR LLLL HHHHHHHH HHHHHHHH HHHHHHHH

其中,S 位和R 位是各個架構平臺通用的,L 和H 構成的28 bit 可以由每個架構平臺獨立實現。

S 是標志位,如果被設置則說明參數過多(過多的標準以該32 bit 數據能表示數據為準)則使用方法簽名的方式進行參數解析;

R 表示返回值的數據類型;

L 表示需要用棧傳參的部分所需的內存大小,單位為8 bit;

H 表示解析參數過程中需要對double 或long long 數據進行插入空白數據的情況時進行標志設定,當某個H 被設置成1 后,在拷貝下一個數據到堆棧之前應該先跳過32 bit;

以一個簡單的實例來加深對各標志位的理解:生成jniHints 的重要中間變量如下:

//通過dexProtoGetShorty(proto)獲取signature

const char* sig=dexProtoGetShorty(proto);

int padFlags;

int stackOffset,padMask;

stackOffset=padFlags=0;

padMask=0x00000001

假設本地方法對對應的signature 為”IZBIJCD”,在這種情況下,各變量的結果為

padFlags=0x00000088

對應二進制為:

0000 0000 0000 0000 0000 0000 1000 1000 padMask=0x00000400

對應二進制為:

0000 0000 0000 0000 0000 0100 0000 0000

stackOffset=10

jniArgInfo 的內容為0x44000088

各個參數在寄存器和棧中的位置如圖1 所示。

圖1

圖1 中,棧開始的地址是8 byte 對齊的0x10001000,其中第4 個參數和第6 個參數為64 bit數據,也需要8 byte 對齊。但是在存儲第3 個參數后的32 bit 數據地址0x10001004 并不是64 bit 對應的,所以填充一個32 bit 的pad。由上圖可以看到,需要開辟一個4·2 字大小的空間,這就是為什么jniArgInfo 中的L 位為0100。

第一個布爾類型的參數Arg1(Z)與第2 個字節類型的參數Arg2(B)分別存儲在R2、R3 中,這是由ARM 體系結構APTCS 規則決定的。前4 個參數(假設前4 個參數大小均為32 bit 或以下)分別由R0、R1、R2、R3 傳遞,其它多余的參數由棧傳遞。但是JNI 機制中的本地方法的實現中第1、第2 個參數為兩個固定的參數,并不需要虛擬機來傳遞,所以Java中調用本地方法時傳遞過來的第1 個參數對應本地方法中第3 個參數,依此類推。這也是為什么上例中的stackOffset 為10,但只為棧開辟了8 字的空間。

ARM 架構的jniArgInfo 之所以這樣表示是由ARM 架構決定的,如之前所述的ARM 架構中long long 和double 數據要棧中要以64 bit 對齊。因此在一個新的架構上實現Dalvik 虛擬機之前,需要了解該架構編譯相關ABI 的詳細內容,包括基本數據類型在內存中的對齊方式、入口棧地址的對齊方式、函數調用規范。

基于自主內核Unity 架構的Tiger,long long 和double 數據是以4 byte 方式對齊的,所以L 位是不需要的,需要開辟棧的大小可以直接存在H 位中。U-Core 架構下的jniArgInfo 可以表示為:

SRRR0000 00000000 00000000 HHHHHHHH

本地方法調用橋實現的最后一步就是用匯編實現參數的傳遞,jniArgInfo 只是為了參數的傳遞做準備。這部分內容在CallEABI.S 中完成,它實現了一個名為dvmPlatformInvoke 的函數,為了保持接口的一致性,最好保持該函數的名稱。該函數通過解析jniArgInfo,將Argv 中的內容復制到對應的寄存器或堆棧中,Argv 中內容的復制必須嚴格的遵守對應架構的函數傳參數規則。

3 Dalvik 虛擬機的優化

利用Oprofile 工具,在SEP0611 開發板上對Android 應用進行數據記錄,得到以下結果:

Profiling through timer interrupt

TIMER:0|

samples| % |

------------------

14275 44.1172 libdvm.so

5535 17.1060 libGAL.so

3991 12.3343 vmlinux

3071 9.4910 libGLESv1_CM_VIVANTE.so

2105 6.5055 libc.so

928 2.8680 libandroid_runtime.so

656 2.0274 libEGL_VIVANTE.so

521 1.6102 libGLESv1_CM.so

242 0.7479 galcore

213 0.6583 linker

178 0.5501 libm.so

其中第1 項libdvm.so 就是Dalvik 虛擬機,它占用CUP 時鐘的比率最高,達到了44.117 2%,遠高于其他進程,由此,對Dalvik 虛擬機進行優化是非常有必要的。

Dalvik 虛擬機中字節碼實現的集合我們稱之為Java 虛擬機的執行引擎。執行引擎是Java 程序運行的核心部份,它由純解釋器或JIT(Just in time)解釋器編譯器構成。通過Oprofile 工具記錄虛擬機測試軟件CaffineMark,可以看到解釋器更是占到了運行時間的90+%,因此我們可以看到Dalvik 虛擬機優化的重心就是在執行引擎。

3.1 解釋器的優化

執行引擎的核心是解釋器,解釋器的基本構成是一個個的解釋例程。解釋例程的執行效率直接影響整個虛擬機的性能。提高解釋器性能的最好途徑無疑是用匯編重寫解釋器。雖然解釋器的實現有很多種,但Android 官方實現的Mtemp 解釋器無疑是最適合嵌入式設備的,因此在一個新的架構上對解釋器進行優化時無需閉門造車。

Android 源碼中Dex 字節碼功能用C 語言作出了描述,給出了解釋器平臺無關的實現,這就是為什么在實現本地方法調用橋后就完成了移植工作。同時官方針對ARM 架構用匯編重寫了解釋器,這使得在一個新的架構上用匯編重寫解釋器的難度降到最低。同時,我們可以看出執行引擎可以與平臺無關。

在優化解釋器之前必須對Dalvik 虛擬機的Dex字節碼有深入的了解,從Dex 字節碼的實現我們可以看出Dalvik 虛擬機是基于寄存器的。

基于寄存器[7]和基于棧這個問題體現在虛擬機底層對字節碼的處理方面。Dex 字節碼是dalvik 虛擬機能直接解釋執行的最小單位,它的指令格式與匯編類似,有第1 操作寄存器,第2 操作寄存器,立即數等。如有一條字節碼為:add-int/2addr V0,V1。這里的V 表示的是虛擬機中的寄存器,它是區別于r 而命名的。值得注意的是,CPU 上是沒有兩個寄存器與V0、V1 相對應的。所以我們稱V0、V1 為虛擬機寄存器,它是用一個棧進行模擬的,所以這條指令的執行效率要遠遠低于真正的匯編:add V0,V0,V1。而對這條Dex 字節碼的執行我們稱之為解釋執行,它需要若干條真正的匯編指令進行功能模擬。當然用C 語言進行功能模擬的代價要比匯編模擬的效率低很多。

3.2 即時編譯

JIT(Just in time)是執行引擎實現的一個可選擇模塊,即執行引擎可以由解釋器單獨構成,也可以是解釋和JIT 編譯器配合工作共同組建。Android系統從2.2 開始在Dalvik 虛擬機中真正意義上的實現了JIT 即時編譯器[8],經過專業的虛擬機性能測試軟件測試我們可以發現虛擬機性能成倍的增長。當然,為了實現新架構平臺的JIT 需要付出很大的代價。主要包括特定字節碼的匯編模板實現、對應架構LIR 指令集全集的模擬,當然,為了配合解釋器工作,解釋器中也需要實現相應對JIT 的處理。

Dalvik 虛擬機中JIT 的被設計成一個可變目標的即時編譯,即JIT 的實現大部分均與目標平臺的架構無關,包括JIT 的整個框架是平臺無關的、Dex 字節碼到MIR 的格式的轉換可以適用于任何一個平臺。在一個新的架構上實現JIT 只需完成MIR 到LIR 的轉換和最終目標指令集的模擬,類似于實現一個小型的編譯器。但即使是這樣,工作量還是非常龐大的,同時找一個有效可行的調試方法或技術路線也是相當有難度的。在一個新的架構上實現JIT 之前需要認真的評估一下工作量和JIT 帶來的實在的好處。

經過專業的虛擬機性能測試軟件測試表明JIT確實能使虛擬機性能成倍的提升,但這個數具對于用戶來說并無知曉。從用戶體驗的角度出發,筆者進行了大量的應用程序的測試,包括應用程序打開的速度,程序運行過程的反應的速度等測試項。結果表明,JIT 對用戶體驗并無影響。同時,引入JIT后,目標設備可用的內存相比要減少,這是由JIT 的特性決定的:以內存空間換取運行效率。

4 小結

本文對Dalvik 虛擬機在SEP0611 國產自主SoC上的移植和優化的方法進行了分析,通過對虛擬機中的JNI 機制進行研究,找到了在虛擬機移植中的關鍵環節,即本地調用橋(Callbrige)。在滿足了特定架構平臺下數據類型的對齊要求和特定架構下函數調用傳參規則兩個要求后,實現了本地調用橋,在測試中發現Dalvik 虛擬機有很大的優化余地,提出了優化方法,解釋器的優化最好途徑是用匯編重寫解釋器,同時對加入即時(JIT)編譯器的工作量和優點,進行了初步的探討。

[1] 韓超,梁泉. Android 系統原理及開發要點詳解[M]. 北京:電子工業出版社,2010:64.

[2] Palo Alto. Google’s Android becomes the World’s Leading Smart Phone Platform[EB/OL]. http://www. canalys. com/pr/2011/r2011013.html,2011-04-25.

[3] Googe Inc. Dalvik Virture Machine[EB/OL]. http://www. dalvikvm.com,2007.

[4] Bill Venners,著.曹曉鋼,蔣靖, ,等譯.深入Java 虛擬機[M].北京:機械工業出版社,2006.

[5] 周志明. 深入理解Java 虛擬機[M]. 北京:機械工業出版社,2011.

[6] ARM Information Center[EB/OL]http://infocenter.arm.com.

[7] 楊豐盛. Android 技術內幕[M]. 北京:機械工業出版社,2011:9.

[8] 李文生,編譯.原理與技術[M].北京:清華大學出版社,2009.

猜你喜歡
優化方法
超限高層建筑結構設計與優化思考
房地產導刊(2022年5期)2022-06-01 06:20:14
民用建筑防煙排煙設計優化探討
關于優化消防安全告知承諾的一些思考
一道優化題的幾何解法
由“形”啟“數”優化運算——以2021年解析幾何高考題為例
學習方法
用對方法才能瘦
Coco薇(2016年2期)2016-03-22 02:42:52
四大方法 教你不再“坐以待病”!
Coco薇(2015年1期)2015-08-13 02:47:34
賺錢方法
捕魚
主站蜘蛛池模板: 国产精品成人观看视频国产 | 日韩a级毛片| 伊在人亞洲香蕉精品區| 毛片网站在线播放| 91在线精品麻豆欧美在线| 1级黄色毛片| 亚洲成A人V欧美综合天堂| JIZZ亚洲国产| 色噜噜狠狠狠综合曰曰曰| 日韩AV无码一区| 国产精品欧美激情| 国产专区综合另类日韩一区| 婷婷伊人五月| 欧美成人怡春院在线激情| 亚洲bt欧美bt精品| 欧美日韩一区二区三区在线视频| 亚洲欧洲日产国产无码AV| 国产超碰在线观看| 伊人激情综合| 久久久久亚洲精品无码网站| 成人在线不卡| 亚洲国产理论片在线播放| 久久国语对白| 亚洲欧美国产视频| 国产精品成人观看视频国产 | 欧美国产菊爆免费观看| 五月激激激综合网色播免费| 456亚洲人成高清在线| 免费激情网站| 二级特黄绝大片免费视频大片| 亚洲黄网在线| 色窝窝免费一区二区三区| 国产乱人乱偷精品视频a人人澡| 不卡午夜视频| 自拍偷拍欧美日韩| 啊嗯不日本网站| 热九九精品| 欧美视频二区| 在线视频精品一区| 中文字幕在线免费看| 亚洲浓毛av| 免费在线一区| 国产一区二区视频在线| 国产精品久久久久久久伊一| 制服丝袜无码每日更新| 成人亚洲天堂| 日韩无码真实干出血视频| 国产乱人激情H在线观看| 免费A∨中文乱码专区| 亚洲成肉网| 一区二区三区四区日韩| 成人国产小视频| 国产网友愉拍精品视频| 午夜少妇精品视频小电影| 国产一区二区福利| 无码福利视频| 国产无吗一区二区三区在线欢| 国产精品乱偷免费视频| 国产精品自在拍首页视频8| 亚洲成人精品| 国产精品视频导航| 亚洲 日韩 激情 无码 中出| 国产黄在线观看| 69视频国产| 国产91无码福利在线| 国产乱子伦手机在线| 久久精品一卡日本电影| 看你懂的巨臀中文字幕一区二区| 久久国产精品77777| 波多野结衣一区二区三区88| 69国产精品视频免费| 992tv国产人成在线观看| 久久这里只精品国产99热8| 国产区免费| 日韩人妻无码制服丝袜视频| 亚洲精品片911| 91精品久久久久久无码人妻| 无码一区二区波多野结衣播放搜索| 青草午夜精品视频在线观看| 亚洲系列中文字幕一区二区| 精品无码一区二区三区电影| 久久精品最新免费国产成人|