Java這套編程語言有一項重要的優點也有一項缺點,優點是「開發一次程式碼能在任何平臺上執行」,而其缺點則是其執行效能。讓Java程式碼具備極高移轉性(portable)的機制也同時讓Java程式碼執行起來相當緩慢。
Java的應用長久以來一直局限在PC、伺服器等環境,但現在Java已逐漸跨入嵌入式方案市場,主要原因就是互動電視與手機的掘起。
為何選擇Java?
互動電視的市場從來一直都沒有完善整合過,不同的衛星與有線電視業者、不同的軟體供應商、以及不同的視訊轉換器制造商等都運用各自不同的建置技術,所以若有一家有線電視業者希望開發一個應用程式,就必須為每款計畫中要支援的電視或機頂盒設備撰寫不同的程式碼。這讓業者投入非常多的資源,卻得不到相對的利潤回收。
為解決這個問題,全球業界開發出兩套標準。其中一套名為MHP-多媒體家庭平臺,這套在歐洲制定的標準能支援全球市場。另一套是OCAP-Open Cable Application Platform是由Cable Laboratories所開發的美國有線電視標準,Cable Laboratories由有線電視業者所創立,其組織成立宗旨在制定各種開放性標準。MHP與OCAP這兩套標準相當類似(見圖示),事實上,OCAP大部分的規格就是引用自MHP,因此,當這些標準被推廣建置后,業者就能依照標準開發互動電視應用程式,而不必擔心這個應用程式將來要在那種電視或機頂盒上執行的問題。
在建置工作方面,支援OCAP標準的地區將由有線電視業者負責建置,這意謂著OCAP的建置一旦開始就會在一夕之間發生,因為當有線電視業者開始建置及要求支援OCAP時,他們所推出的每一部設備都將會支援OCAP。反觀MHP就比較沒有強制性。歐洲的廣播業者-包括衛星與地面廣播業,大多透過零售商店供應其設備,因此使用者有選擇產品的權力。他們可選購支援或不支援MHP功能的產品,雖然支援MHP技術的產品會比較昂貴,但MHP產品的數量仍會持續成長。由于產品的價差及目前消費者可能感覺不到MHP的明顯價值,擁有MHP功能的設備成長將是漸進式。但預估在未來5年內,這兩種產品(MHP & OCAP)都會攀升至數百萬部的年出貨量。
Java解決方案
Java硬體加速方案約在5年前出現,這些方案嘗試在主要處理器旁加裝一個小型處理器來專責執行Java程式,希望藉此解決效能問題。值得一提的是運用了硬體加速器后,Java的執行速度確實提升了,而且它不需任何額外的記憶體-在5年前針對手機來說,這是一個很重要的優點。其缺點則是須使用額外硬體及功耗的增加。
在現今技術的發展下,即使針對手機來說,記憶體容量需求的問題已經不復存在;以往受到記憶體數量限制的系統(主要是手機)已不再有這類問題。硬體加速器的其中一項優勢也就因此消失。另外一個對硬體加速器不利的就是軟體加速技術經歷長久的研發,已經得到了相當的進展。在效能方面已遠遠超越硬體加速器,且沒有硬體解決方案須使用額外硬體與增加功耗的問題。
為了分析軟體解決方案的效能如何超越舊型硬體方案,我們必須先回顧Java的演進歷史。早的Java建置方案是由一套轉譯程式(interpreter),將每個Java指令都轉譯成對等的微處理器指令,并根據轉譯后的指令先后次序依序執行,由于一個Java指令可能被轉譯成十幾或數十幾個對等的微處理器指令,這種模式執行的速度相當緩慢。
針對這個問題,業界首先開發出JIT(just in time)編譯器。當Java執行runtime環境時,每遇到一個新的類別(class:類別是Java程式中的功能群組),類別是Java程式中的功能群組-JIT編譯器在此時就會針對這個類別進行編譯(compile)作業。經過編譯后的程式,被優化成相當精簡的原生型指令碼(native code),這種程式的執行速度相當快。花費少許的編譯時間來節省稍后相當長的執行時間,JIT這種設計的確增加不少效率,但是它并未達到的效能,因為某些極少執行到的Java指令在編譯時所額外花費的時間可能比轉譯器在執行時的時間還長,針對這些指令而言,整體花費的時間并沒有減少。
基于對JIT的經驗,業界發展出動態編譯器(dynamic compiler),動態編譯器僅針對較常被執行的程式碼進行編譯,其余部分仍使用轉譯程式來執行。也就是說,動態編譯器會研判是否要編譯每個類別。動態編譯器擁有兩項利器:一是轉譯器,另一則是JIT,它透過智慧機制針對每個類別進行分析,然后決定使用這兩種利器的哪一種來達到化的效果。動態編譯器針對程式的特性或者是讓程式執行幾個循環,再根據結果決定是否編譯這段程式碼。這個決定不見得正確,但從統計數字來看,這個判斷的機制正確的機會相當高。事實上,動態編譯器會根據「歷史資料」做決策,所以程式執行的時間愈長,判斷正確的機率就愈高。以整個結果來看,動態編譯器產生的程式碼執行的速度超越以前的JIT技術,平均速度可提高至50%。
但軟體加速如何超越硬體加速,尤其是特別設計的「硬體加速器」?我們可以從下文了解原因:
開發Java加速器時,工程師可專注于開發硬體的小巧,也可專注于加快處理速度。為了Java的可攜性(portability),讓Java程式碼能在所有硬體架構上執行,Sun設計的Java指令結構迥異于其他硬體架構,因此要開發一套Java加速器是相當復雜的工作。工程師不可能將硬體加速器設計得過大,因為這會使該加速器失去競爭力,工程師只好犧牲加速的功能來縮減加速器的尺寸。這類加速器在執行Java程式時的速度超過一般簡易的轉譯器,但比不上如動態編譯器的先進的軟體加速器,以目前先進軟體加速器的普及,拿簡易的軟體轉譯器來做比較已經沒有意義。
軟體方案速度較高的另一項原因是因為處理器是在原生模式下執行程式碼,因此若您針對某種處理器編譯Java程式碼,處理器就能在速度的模式下執行該程式。動態編譯器能提供接近原生模式的效能,并僅針對重要的程式區段來作編譯。硬體加速器并未以處理器原生模式來執行程式碼,而仍是以Java程式來執行。
Java指令架構在效能提升方面造成許多障礙:首先,它不允許暫存器,因此所有的運算都是在堆疊(stack)中操作。運算用的資料及結果只能放在堆疊中,運算時再從堆疊中取出使用。Java指令架構亦不允許C語言所支援的指標(pointer)。若在一個類別中有某個數值,我們希望讓另一個類別使用該數值時,在C語言中僅須用一個指標指向記憶體中儲存該數值的位址。因為指標若誤用可能造成記憶體資料錯亂,Java指令架構為維持程序執行的穩定度,因此不允許使用指標,其代價就是必須使用更多的步驟來移動資料。在傳遞數值時,就算該數值不會有改變,也必須從一個記憶體位址復制到另一個記憶體位址。這種方式的執行速度遠低于只傳遞一個會指向資料所在地的指標。
上面所提的這些障礙都是硬體加速器無法解決的。因此,盡管硬體加速器出現已有4、5年的時間,卻不像軟體解決方案一樣已經有數個世代的改進,現在其效能已經遠落后軟體加速器。
記憶體容量的問題不復存在
以往手機所面臨記憶體容量有限的困境,因為Java編譯器會耗盡所有記憶體,因此手機無法搭載任何編譯器資源,在這樣的環境下,當硬體加速器在當年(1999)問市時,對手機運用而言,它合理避免了對記憶體容量額外負擔的問題。
但今天即使對手機而言,這種情況已不復存在。現在就算是低階的手機也都搭載了2~3 Mbytes的記憶體。以在MIPS架構中執行的Esmertec動態編譯器為例,它僅占用了235 Kbyte的記憶體空間,在所有記憶體中占用非常小的比率,因此這方面的設計限制已然消失,而記憶體充裕的狀況使業界能夠放手開發出各種優異的軟體解決方案。
一點,現今的手機幾乎都搭配彩色螢幕,支援富含大量繪圖元素的應用。手機微控制器遇到的問題是繪圖加速,而不是Java。若廠商所設計的產品僅搭載簡單的螢幕以及少量的記憶體,那就可能需要一個Java硬體加速器,但在大多數狀況下,軟體解決方案都遠遠超過硬體解決方案!