java的僞共享

緩存系統中是以緩存行(cache line)為單位存儲的。緩存行是2的整數冪個連續字節,一般為32-256個字節。最常見的緩存行大小是64個字節。當多線程修改互相獨立的變量時,如果這些變量共享同一個緩存行,就會無意中影響彼此的性能,這就是偽共享。緩存行上的寫競爭是運行在SMP系統中並行線程實現可伸縮性最重要的限制因素。有人將偽共享描述成無聲的性能殺手,因為從代碼中很難看清楚是否會出現偽共享。

緩存行

由於共享變量在CPU緩存中的存儲是以緩存行為單位,一個緩存行可以存儲多個變量(存滿當前緩存行的字節數);而CPU對緩存的修改又是以緩存行為最小單位的,那麼就會出現上訴的偽共享問題。

Cache Line可以簡單的理解為CPU Cache中的最小緩存單位,今天的CPU不再是按字節訪問內存,而是以64字節為單位的塊(chunk)拿取,稱為一個緩存行(cache line)。當你讀一個特定的內存地址,整個緩存行將從主存換入緩存,並且訪問同一個緩存行內的其它值的開銷是很小的。

java的偽共享

看如下代碼示例:

int[] arr = new int[64 * 1024 * 1024];

long start = System.nanoTime();

for (int i = 0; i < arr.length; i++) {

arr[i] *= 3;

}

System.out.println(System.nanoTime() - start);

long start2 = System.nanoTime();

for (int i = 0; i < arr.length; i += 16) {

arr[i] *= 3;

}

System.out.println(System.nanoTime() - start2);

表面上看,第二個循環工作量為第一個循環的1/16;但是執行時間是相差不大的,假設在內存規整的情況下,每16個int 佔用4*16=64字節,正好一個緩存行,也就是說這兩個循環訪問內存的次數是一致的。導致耗時相差不大。

java的偽共享

尚學堂12大精英團隊+各類實戰項目,真正實現1+1>10的目標效果。幫助學員迅速成長,持久騰飛,成就學員“高富帥”人生;幫助企業技術和團隊成長,成就百年中華名企;助力中國持續成為世界強國而貢獻力量。尚學堂12大精英團隊,覆蓋IT行業十大領域,實戰團隊240人,服務學員累計超過10萬人,就業合作企業數量500+。


分享到:


相關文章: