[英]Why access volatile variable is about 100 slower than member?
這里我寫了一個關於local、member、volatile成員訪問速度的測試:
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)上的結果:
Round:1空車:5 Local:10 Member:312 VMember:33378
輪數:2空車數:31 本地數:0 會員數:294 V會員數:33180
輪次:3空車:0 本地:0 會員:306 VM會員:33085
回合數:4空數:0 本地數:0 會員數:300 虛擬會員數:33066
輪次:5空車:0 本地:0 會員:303 VM會員:33078
輪數:6空車數:0 本地數:0 會員數:299 虛擬會員數:33398
輪數:7空車數:0 本地數:0 會員數:305 虛擬會員數:33139
輪次:8空車:0 本地:0 會員:307 VM會員:33490
輪次:9空車:0 本地:0 會員:350 VM會員:35291
輪次:10空車:0 本地:0 會員:332 VM會員:33838
令我驚訝的是,訪問 volatile 成員比普通成員慢 100 倍。 我知道關於 volatile 成員有一些突出的特性,比如對它的修改將立即對所有線程可見,對 volatile 變量的訪問點起着“內存屏障”的作用。 但是所有這些副作用會是慢 100 倍的主要原因嗎?
PS:我也在Core II CPU機器上做過測試。 大約是9:50,慢了大約5倍。 似乎這也與 CPU 架構有關。 5倍還是很大吧?
volatile 成員從不被緩存,所以它們直接從主內存中讀取。
訪問volatile
變量會阻止 CPU 在訪問前后對指令進行重新排序,這通常會減慢執行速度。
訪問volatile
會阻止一些 JIT 優化。 如果您有一個實際上不執行任何操作的循環,這一點尤其重要,因為 JIT 可以優化此類循環(除非您有一個 volatile 字段)如果您“長時間”運行循環,差異應該會增加更多。
在更實際的測試中,您可能預計volatile
對關鍵代碼的處理速度要慢 30% 到 10 倍。 在大多數實際程序中,它幾乎沒有什么區別,因為 CPU 足夠聰明,可以“意識到”只有一個內核在使用易失性字段並緩存它而不是使用主內存。
使用volatile會直接從內存中讀取,這樣cpu的每個核心都會在下一次get時從變量中獲取變化,沒有使用cpu緩存,不會使用寄存器,L1~L3緩存技術,讀取自
這就是為什么使用 volatile 時你的結果會慢大約 100 倍。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.