承接上文CPU緩存一致性原理
雙擊QQ.exe從磁盤加載到內(nèi)存里面,內(nèi)存里面就會有了一個進程,進程產(chǎn)生的時候會產(chǎn)生一個主線程,就是main方法所在的線程,cpu會找到main開始的地方,把它的指令讀取過來放到程序計數(shù)器,把數(shù)據(jù)放到寄存器,然后ALU開始做計算,一步一步來執(zhí)行整個程序,這就是普通程序執(zhí)行的過程。
cpu速度要比內(nèi)存的速度快100倍,中間有各種各樣的緩存,最常見的是三級緩存,由于它的速度非???,在執(zhí)行指令的時候也會有一些優(yōu)化,比如現(xiàn)在有2條指令,一個是mov指令即從內(nèi)存中讀取一個數(shù)據(jù)到某一個寄存器中,第二個指令是把寄存器中的指令數(shù)值加1,如果嚴格按照前后寫的效率執(zhí)行,會發(fā)現(xiàn)它的效率比較低;第一條指令從內(nèi)存中讀數(shù)據(jù)出來,cpu等待99個時間周期,如果讀完第一個指令之后,才可以執(zhí)行第二個指令的話,cpu將會有99個空檔期,所以現(xiàn)在的cpu設(shè)計是流水線式的設(shè)計(采用流水線式后,并沒有加速單條指令的執(zhí)行,每條指令的操作步驟一個也不能少,只是多條指令的不同操作步驟同時執(zhí)行,因而從總體上看加快了指令流速度,縮短了程序執(zhí)行時間),發(fā)送一條指令在等待內(nèi)存數(shù)據(jù)返回的過程當中,會把后面這條指令執(zhí)行了即后面的指令跑到前面先執(zhí)行了,簡單稱為cpu的亂序執(zhí)行,主要是為了提高效率,在等待費時的指令執(zhí)行的時候,優(yōu)先執(zhí)行后面的指令。
證明cpu亂序執(zhí)行是存在的
這里有個死循環(huán),每一次循環(huán)都會把這4個值(x、y、a、b)設(shè)置為0,每一次循環(huán)都會起2個線程,第一個線程會執(zhí)行a=1、x=b,第二個線程會執(zhí)行b=1、y=a;假設(shè)所有的語句都是按照順序執(zhí)行的,從多線程微觀的角度進行時間順序上的排列組合,你會發(fā)現(xiàn)會有各種各樣的組合場景:
比如第一種組合,
第一種組合先執(zhí)行a=1、x=b,后執(zhí)行b=1、y=a,得到的結(jié)果是x=0、y=1。
這6種排列組合的結(jié)果無論如何都不可能得到x=0、y=0的情況即只要按照順序執(zhí)行,絕對不會出現(xiàn)x=0、y=0。
這是數(shù)學上的排列組合,但cpu執(zhí)行指令的時候未必是按照順序執(zhí)行的。
出現(xiàn)x=0、y=0的情況比較少見,為什么這么難出現(xiàn)?什么樣的組合下才會出現(xiàn)?
跑了270多萬次才出現(xiàn)了一次x=0、y=0的情況,
這兩種是亂序執(zhí)行的排列組合,比如第一個場景是線程1先執(zhí)行x=b、線程2執(zhí)行y=a,切換到線程1執(zhí)行a=1,切換到線程2執(zhí)行b=1,結(jié)果是x=0、y=0。
只有這2種場景,2個線程的這2個指令都得顛倒順序才會出現(xiàn),這種很難出現(xiàn),不管怎樣,得出一個結(jié)論:cpu內(nèi)部是亂序執(zhí)行的。
單線程的情況下,2個指令亂了順序執(zhí)行沒有關(guān)系,反正最終的結(jié)果是一樣的,但是在多線程的情況下,非常有可能出現(xiàn)你不想看到的情形,比如x=0、y=0的情況,比如在預(yù)知中沒有這種情況,但是多線程的情況下,會出現(xiàn),所以一定會影響整個多線程程序的運行,單線程的程序不會影響。
有了as-if-serial(看上去像序列化的)指令就可以隨便變換順序,只要維持最終一致性即可;單線程的重排序只需要保證最終的一致性,比如a=b、y=1,隨便重排序,只要能保證單線程的最終一致性。
審核編輯:湯梓紅
-
寄存器
+關(guān)注
關(guān)注
31文章
5301瀏覽量
119862 -
cpu
+關(guān)注
關(guān)注
68文章
10813瀏覽量
210880 -
指令
+關(guān)注
關(guān)注
1文章
606瀏覽量
35618 -
緩存
+關(guān)注
關(guān)注
1文章
229瀏覽量
26635 -
線程
+關(guān)注
關(guān)注
0文章
504瀏覽量
19636
發(fā)布評論請先 登錄
相關(guān)推薦
評論