這篇文章主要講解了“C++中的偽共享是什么”,文中的講解內(nèi)容簡單清晰,易于學(xué)習(xí)與理解,下面請(qǐng)大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“C++中的偽共享是什么”吧!
我們是公司2013年成立的成都網(wǎng)站建設(shè)公司,提供網(wǎng)站建設(shè),電商網(wǎng)站設(shè)計(jì)開發(fā),外貿(mào)營銷網(wǎng)站建設(shè),響應(yīng)式網(wǎng)頁設(shè)計(jì),小程序制作、等服務(wù)。為客戶創(chuàng)造有價(jià)值的品牌營銷體驗(yàn),讓互聯(lián)網(wǎng)提升企業(yè)的競爭力!為了進(jìn)行下面的討論,我們需要首先熟悉緩存行的概念,學(xué)過操作系統(tǒng)課程存儲(chǔ)結(jié)構(gòu)這部分內(nèi)容的同學(xué)應(yīng)該對(duì)存儲(chǔ)器層次結(jié)構(gòu)的金字塔模型印象深刻,金字塔從上往下代表存儲(chǔ)介質(zhì)的成本降低、容量變大,從下往上則代表存取速度的提高。位于金字塔模型最上層的是CPU中的寄存器,其次是CPU緩存(L1,L2,L3),再往下是內(nèi)存,最底層是磁盤,操作系統(tǒng)采用這種存儲(chǔ)層次模型主要是為了解決CPU的高速與內(nèi)存磁盤低速之間的矛盾,CPU將最近使用的數(shù)據(jù)預(yù)先讀取到Cache中,下次再訪問同樣數(shù)據(jù)的時(shí)候,可以直接從速度比較快的CPU緩存中讀取,避免從內(nèi)存或磁盤讀取拖慢整體速度。
CPU緩存的最小單位就是緩存行,緩存行大小依據(jù)架構(gòu)不同有不同大小,最常見的有64Byte和32Byte,CPU緩存從內(nèi)存取數(shù)據(jù)時(shí)以緩存行為單位進(jìn)行,每一次都取需要讀取數(shù)據(jù)所在的整個(gè)緩存行,即使相鄰的數(shù)據(jù)沒有被用到也會(huì)被緩存到CPU緩存中(這里又涉及到局部性原理,后面文章會(huì)進(jìn)行介紹)。
在單核CPU情況下,上述方法可以正常工作,可以確保緩存到CPU緩存中的數(shù)據(jù)永遠(yuǎn)是“干凈”的,因?yàn)椴粫?huì)有其他CPU去更改內(nèi)存中的數(shù)據(jù),但是在多核CPU下,情況就變得更加復(fù)雜一些。多CPU中,每個(gè)CPU都有自己的私有緩存(可能共享L3緩存),當(dāng)一個(gè)CPU1對(duì)Cache中緩存數(shù)據(jù)進(jìn)行操作時(shí),如果CPU2在此之前更改了該數(shù)據(jù),則CPU1中的數(shù)據(jù)就不再是“干凈”的,即應(yīng)該是失效數(shù)據(jù),緩存一致性就是為了保證多CPU之間的緩存一致。
Linux系統(tǒng)中采用MESI協(xié)議處理緩存一致性,所謂MESI即是指CPU緩存的四種狀態(tài):
M(修改,Modified):本地處理器已經(jīng)修改緩存行,即是臟行,它的內(nèi)容與內(nèi)存中的內(nèi)容不一樣,并且此 cache 只有本地一個(gè)拷貝(專有);
E(專有,Exclusive):緩存行內(nèi)容和內(nèi)存中的一樣,而且其它處理器都沒有這行數(shù)據(jù);
S(共享,Shared):緩存行內(nèi)容和內(nèi)存中的一樣, 有可能其它處理器也存在此緩存行的拷貝;
I(無效,Invalid):緩存行失效, 不能使用。
每個(gè)CPU緩存行都在四個(gè)狀態(tài)之間互相轉(zhuǎn)換,以此決定CPU緩存是否失效,比如CPU1對(duì)一個(gè)緩存行執(zhí)行了寫入操作,則此操作會(huì)導(dǎo)致其他CPU的該緩存行進(jìn)入Invalid無效狀態(tài),CPU需要使用該緩存行的時(shí)候需要從內(nèi)存中重新讀取。由此就解決了多CPU之間的緩存一致性問題。
何謂偽共享?上面我們提過CPU的緩存是以緩存行為單位進(jìn)行的,即除了本身所需讀寫的數(shù)據(jù)之外還會(huì)緩存與該數(shù)據(jù)在同一緩存行的數(shù)據(jù),假設(shè)緩存行大小是32字節(jié),內(nèi)存中有“abcdefgh”八個(gè)int型數(shù)據(jù),當(dāng)CPU讀取“d”這個(gè)數(shù)據(jù)時(shí),CPU會(huì)將“abcdefgh”八個(gè)int數(shù)據(jù)組成一個(gè)緩存行加入到CPU緩存中。假設(shè)計(jì)算機(jī)有兩個(gè)CPU:CPU1和CPU2,CPU1只對(duì)“a”這個(gè)數(shù)據(jù)進(jìn)行頻繁讀寫,CPU2只對(duì)“b”這個(gè)數(shù)據(jù)進(jìn)行頻繁讀寫,按理說這兩個(gè)CPU讀寫數(shù)據(jù)沒有任何關(guān)聯(lián),也就不會(huì)產(chǎn)生任何競爭,不會(huì)有性能問題,但是由于CPU緩存是以緩存行為單位進(jìn)行存取的,也是以緩存行為單位失效的,即使CPU1只更改了緩存行中“a”數(shù)據(jù),也會(huì)導(dǎo)致CPU2中該緩存行完全失效,同理,CPU2對(duì)“b”的改動(dòng)也會(huì)導(dǎo)致CPU1中該緩存行失效,由此引發(fā)了該緩存行在兩個(gè)CPU之間“乒乓”,緩存行頻繁失效,最終導(dǎo)致程序性能下降,這就是偽共享。
避免偽共享主要有以下兩種方式:
1.緩存行填充(Padding):為了避免偽共享就需要將可能造成偽共享的多個(gè)變量處于不同的緩存行中,可以采用在變量后面填充字節(jié)的方式達(dá)到該目的。
2.使用某些語言或編譯器中強(qiáng)制變量對(duì)齊,將變量都對(duì)齊到緩存行大小,避免偽共享發(fā)生。
感謝各位的閱讀,以上就是“C++中的偽共享是什么”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對(duì)C++中的偽共享是什么這一問題有了更深刻的體會(huì),具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是創(chuàng)新互聯(lián)網(wǎng)站建設(shè)公司,,小編將為大家推送更多相關(guān)知識(shí)點(diǎn)的文章,歡迎關(guān)注!