2012-06-21 83 views
5

在這裏,我寫了一個測試大約地方,成員,volatile成員的訪問速度:爲什麼訪問volatile變量比成員慢100左右?

public class VolatileTest { 

public int member = -100; 

public volatile int volatileMember = -100; 

public static void main(String[] args) { 
    int testloop = 10; 
    for (int i = 1; i <= testloop; i++) { 
     System.out.println("Round:" + i); 
     VolatileTest vt = new VolatileTest(); 
     vt.runTest(); 
     System.out.println(); 
    } 
} 

public void runTest() { 
    int local = -100; 

    int loop = 1; 
    int loop2 = Integer.MAX_VALUE; 
    long startTime; 

    startTime = System.currentTimeMillis(); 
    for (int i = 0; i < loop; i++) { 
     for (int j = 0; j < loop2; j++) { 
     } 
     for (int j = 0; j < loop2; j++) { 
     } 
    } 
    System.out.println("Empty:" + (System.currentTimeMillis() - startTime)); 

    startTime = System.currentTimeMillis(); 
    for (int i = 0; i < loop; i++) { 
     for (int j = 0; j < loop2; j++) { 
      local++; 
     } 
     for (int j = 0; j < loop2; j++) { 
      local--; 
     } 
    } 
    System.out.println("Local:" + (System.currentTimeMillis() - startTime)); 

    startTime = System.currentTimeMillis(); 
    for (int i = 0; i < loop; i++) { 
     for (int j = 0; j < loop2; j++) { 
      member++; 
     } 
     for (int j = 0; j < loop2; j++) { 
      member--; 
     } 
    } 
    System.out.println("Member:" + (System.currentTimeMillis() - startTime)); 

    startTime = System.currentTimeMillis(); 
    for (int i = 0; i < loop; i++) { 
     for (int j = 0; j < loop2; j++) { 
      volatileMember++; 
     } 
     for (int j = 0; j < loop2; j++) { 
      volatileMember--; 
     } 
    } 
    System.out.println("VMember:" + (System.currentTimeMillis() - startTime)); 

} 
} 

這裏是我的X220(I5 CPU)結果:

回合:1 空:5 當地:10 成員:312 VMember:33378

回合:2 空:31 本地:0 成員:294 VMember:33180

回合:3 空:0 本地:0 成員:306 VMember:33085

回合:4 空:0 本地:0 成員:300 VMember:33066

回合:5 空:0 本地:0 會員:303 VMember:33078

回合:6 空:0 本地:0 成員:299 VMember:33398

回合:7 空:0 本地:0 成員:305 VMember:33139

回合:8 空:0 本地:0 會員:307 VMember:33490

回合:9 空:0 本地:0 成員:350 VMember:35291

回合:10 空:0 本地:0 成員:332 VMember:33838

令我驚訝的是訪問易失性構件比正常構件慢100倍。我知道有一些關於volatile成員的高亮功能,比如對它的修改會立即對所有線程都可見,訪問點volatile變量扮演着「內存障礙」的角色。但是,所有這些副作用是否會成爲100倍慢的主要原因?

PS:我也在Core II CPU機器上做過測試。大約9:50,大約慢了5倍。似乎這也與CPU拱有關。 5次還是很大的吧?

+0

可能重複的[Is volatile expensive?](http://stackoverflow.com/questions/4633866/is-volatile-expensive) –

+0

看着它... – DeepNightTwo

回答

3

使用volatile可以防止某些JIT優化。如果你的循環沒有做任何事情,JIT可以優化這些循環(除非你有一個volatile字段),這一點尤其重要。如果你運行循環「long」,那麼這個循環會增加更多。

在更實際的測試中,您可能會預計volatile對於cirtical代碼的採樣速度會降低30%到10倍。在大多數實際的程序中,它幾乎沒有什麼區別,因爲CPU足夠聰明,可以「認識到」只有一個內核正在使用易失性字段並對其進行緩存,而不是使用主內存。

3

訪問volatile變量會阻止CPU在訪問前後重新排序指令,這通常會降低執行速度。

6

易失性成員永遠不會被緩存,所以它們直接從主內存中讀取。

+0

到底。爲什麼這不是被接受的答案。 –

相關問題