天天看點

Java 6 Hotspot 編譯型語言

 sun公司的kohsuke kawaguchi考察了hotspot jit在jdk6 u10 b14 debug版中産生的彙編代碼,并将其記錄在部落格中。該博文着重闡述了java優化的程度。

    kawaguchi 将重點放在兩個主要的地方。首先是循環展開(loop unrolling),它是這樣一種技術:複制循環的每次疊代所調用的指令以構成一個序列。通過減少循環中計算機需要執行的指令,節省了執行時間。jit 将其與預處理和事後分析相結合,同時kawaguchi對此的補充也說明了這樣的事實:編譯器已從循環的快速執行部分當中移除了一個備援的數組索引檢查。此外,結果彙編代碼證明了特定于處理器的優化程度如何。例如,kawaguchi談到了下面的代碼:

private static byte[] foo() { byte[] buf = new byte[256]; for( int i=0; i buf[i] = 0; return buf; }

    所産生的彙編結果使用了特定于amd64晶片的r8-r15通用寄存器彙編代碼。

    其次是圍繞着鎖(locks)而進行的優化。在java中非競态鎖的擷取在不斷地改進,而競态鎖的擷取卻一直存在問題。這個領域的工作還在持續進行中,但是kawaguchi的工作卻說明了幾個已經得到改進的地方。

    這篇文章展示了該hotspot編譯器很多其他的特性,包括強大的内聯——james gosling注意到一篇相關的博文中說“甚至連存儲配置設定和初始化都需要内聯”。這一層級的侵略性(aggression)是可能存在的,部分原因在于 jvm會在必要時做一些潛在不安全的優化。charles nutter在今年初參加lang.net大會時曾對此提出了一個很好的解釋。他也強調了這項工作與jruby的關系,以及與任何面向jvm的語言的關系。

    “過去jvm有多種不同的能力去動态優化和再優化代碼……或許最重要的是必要時的動态“逆優化(deoptimize)”。在處理性能問題時,逆優化(deoptimization)令人非常興奮,因為這意味着你可以進行更多的侵略性優化——對整個應用不确定的未來的潛在的不安全的優化——知道你可以在安全的路徑上回退。一旦你幾次遇到相同的路徑,你就可以内聯整個調用路徑。除非明顯需要,你可以忽略同步保護。你還可以在發現問題之後改變使用的優化集……本質上,在運作過程中你可以安全的“出錯”并且從錯誤中學習。這就是為什麼在特定的基準上java超越了c和c++以及最終在幾乎所有基準上它都能将超越c和c++的主要原因。同時這也是我們的jruby與微軟的ironpython和dlr相比,隻需要做很少的事情就可以獲得可接受的性能的一個關鍵原因。”

    從理論上講,像java這樣的解釋型語言的性能很有可能最終将超越編譯型語言,因為它可以在運作時基于現有硬體進行優化,同時java中不斷提高的對特定于處理器的優化确實令人非常興奮。對于面向java平台的開發者來說,一個額外的好處在于随着新版本 java編譯器的釋出,代碼的性能會不斷改進,而無需對應用的源碼做任何更改。

英文原文:http://www.infoq.com/news/2008/05/hotspot_performance