日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網(wǎng)為廣大站長提供免費收錄網(wǎng)站服務(wù),提交前請做好本站友鏈:【 網(wǎng)站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(wù)(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網(wǎng)站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

CPU每次讀取并不是一個字節(jié)一個字節(jié)的讀取,它會一次讀取一塊內(nèi)容,這“塊”稱之為CPU的緩存行(CPU每次訪問主存會很慢;CPU的高速緩存L1,L2,L3;L1,L2是每個CPU Core獨有的,L3是所有Core共享的。我們可以把緩存行理解為高速緩存的組成最小單元)。最常見的緩存行大小是64byte(每次都會讀取64字節(jié)大?。?。

 

java 偽共享 False Sharing

CPU 個緩存 及 主存

當CPU從主內(nèi)存中讀取一個變量的時候它會把相鄰的數(shù)據(jù)都一次性的加載到緩存中。當訪問相鄰數(shù)據(jù)的時候就不需要再到主存中讀取了,直接從緩存中獲取,提高執(zhí)行效率。


private static class CacheLineData {

private volatile long d1 = 0L;

private volatile long d2 = 0L;

private volatile long d3 = 0L;

private volatile long d4 = 0L;

}

在多核core環(huán)境下,當有多個線程訪問如上變量d1,d2,d3,d4,每個線程都運行在不同的core中


private static CacheLineData cacheLine = new CacheLineData() ;

private static int n = 1000000 ;

public static void main(String[] args) throws Exception {

int loop = 4 ;

Thread[] ts = new Thread[loop] ;

ts[0] = new Thread(() -> {

for (int m = 0; m < n; m++) {

cacheLine.d1 = m ;

}

}) ;

ts[1] = new Thread(() -> {

for (int m = 0; m < n; m++) {

cacheLine.d2 = m ;

}

}) ;

ts[2] = new Thread(() -> {

for (int m = 0; m < n; m++) {

cacheLine.d3 = m ;

}

}) ;

ts[3] = new Thread(() -> {

for (int m = 0; m < n; m++) {

cacheLine.d4 = m ;

}

}) ;

long start = System.currentTimeMillis() ;

for (int i = 0; i < loop; i++) {

ts[i].start() ;

}

for (int i = 0; i < loop; i++) {

ts[i].join() ;

}

System.out.println("耗時:" + (System.currentTimeMillis() - start) + " ms") ;

}

如上代碼有4個線程分別訪問d1,d2,d3,d4。如何產(chǎn)生偽共享的呢?當線程1修改了d1變量后,其它線程的緩存行多會作廢并重新從主存中獲取數(shù)據(jù)(volatile 修飾的變量,在多線程情況下訪問時當有一個線程修改了這個變量,那么會通過消息總線通知其他線程該變量已經(jīng)修改并將其置為invalid狀態(tài),再使用時必須重新從主存中獲取)。

如上示例代碼運行結(jié)果:

50ms左右

當把volatile修飾符去掉后的運行結(jié)果:

private static class CacheLineData {

private long d1 = 0L;

private long d2 = 0L;

private long d3 = 0L;

private long d4 = 0L;

}

7ms左右

方法1、接下來我們可以通過填充的方法來使得每個變量都處在不同的緩存行中。一個long占8個字節(jié)(我們這里按照緩存行64個字節(jié)來算)

private static class CacheLineData {

private volatile long k0, k1, k2, k3, k4, k5, k6, k7 ;

private volatile long d1 = 0L;

private volatile long n0, n1, n2, n3, n4, n5, n6, n7 ;

private volatile long d2 = 0L;

private volatile long z0, z1, z2, z3, z4, z5, z6, z7 ;

private volatile long d3 = 0L;

private volatile long a0, a1, a2, a3, a4, a5, a6, a7 ;

private volatile long d4 = 0L;

}


執(zhí)行結(jié)果:

11ms左右

方法2:在JAVA8中可以通過 @Contended注解

Contended注解可以用于類型上和屬性上,加上這個注解之后虛擬機會自動進行填充,從而避免偽共享。

private static class CacheLineData {

@Contended

private volatile long d1 = 0L;

@Contended

private volatile long d2 = 0L;

@Contended

private volatile long d3 = 0L;

@Contended

private volatile long d4 = 0L;

}

要使Contended注解生效需要啟動jvm時加入如下參數(shù):

-XX:-RestrictContended

執(zhí)行結(jié)果:

13ms左右

關(guān)于變量在其它core中是怎么失效的是通過MESI協(xié)議來完成的。

分享到:
標簽:False Sharing
最新入駐小程序

數(shù)獨大挑戰(zhàn)2018-06-03

數(shù)獨一種數(shù)學(xué)游戲,玩家需要根據(jù)9

答題星2018-06-03

您可以通過答題星輕松地創(chuàng)建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學(xué)四六

運動步數(shù)有氧達人2018-06-03

記錄運動步數(shù),積累氧氣值。還可偷

每日養(yǎng)生app2018-06-03

每日養(yǎng)生,天天健康

體育訓(xùn)練成績評定2018-06-03

通用課目體育訓(xùn)練成績評定