最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

淺談C++性能榨汁機之偽共享

 更新時間:2021年06月09日 10:52:25   作者:lsgxeva  
使給定內(nèi)存位置被一個線程所訪問,可能還是會有乒乓緩存的存在,是因為另一種叫做偽共享(false sharing)的效應(yīng)。即使數(shù)據(jù)存儲在緩存行中,多個線程對數(shù)據(jù)中的成員進行訪問時,硬件緩存還是會產(chǎn)生乒乓緩存。本文將介紹C++中的偽共享

前言

在多核并發(fā)編程中,如果將互斥鎖的爭用比作“性能殺手”的話,那么偽共享則相當于“性能刺客”?!皻⑹帧迸c“刺客”的區(qū)別在于殺手是可見的,遇到殺手時我們可以選擇戰(zhàn)斗、逃跑、繞路、求饒等多種手段去應(yīng)付,但“刺客”卻不同,“刺客”永遠隱藏在暗處,伺機給你致命一擊,防不勝防。具體到我們的并發(fā)編程中,遇到鎖爭用影響并發(fā)性能情況時,我們可以采取多種措施(如縮短臨界區(qū),原子操作等等)去提高程序性能,但是偽共享卻是我們從所寫代碼中看不出任何蛛絲馬跡的,發(fā)現(xiàn)不了問題也就無法解決問題,從而導致偽共享在“暗處”嚴重拖累程序的并發(fā)性能,但我們卻束手無策。

緩存行

為了進行下面的討論,我們需要首先熟悉緩存行的概念,學過操作系統(tǒng)課程存儲結(jié)構(gòu)這部分內(nèi)容的同學應(yīng)該對存儲器層次結(jié)構(gòu)的金字塔模型印象深刻,金字塔從上往下代表存儲介質(zhì)的成本降低、容量變大,從下往上則代表存取速度的提高。位于金字塔模型最上層的是CPU中的寄存器,其次是CPU緩存(L1,L2,L3),再往下是內(nèi)存,最底層是磁盤,操作系統(tǒng)采用這種存儲層次模型主要是為了解決CPU的高速與內(nèi)存磁盤低速之間的矛盾,CPU將最近使用的數(shù)據(jù)預先讀取到Cache中,下次再訪問同樣數(shù)據(jù)的時候,可以直接從速度比較快的CPU緩存中讀取,避免從內(nèi)存或磁盤讀取拖慢整體速度。

CPU緩存的最小單位就是緩存行,緩存行大小依據(jù)架構(gòu)不同有不同大小,最常見的有64Byte和32Byte,CPU緩存從內(nèi)存取數(shù)據(jù)時以緩存行為單位進行,每一次都取需要讀取數(shù)據(jù)所在的整個緩存行,即使相鄰的數(shù)據(jù)沒有被用到也會被緩存到CPU緩存中(這里又涉及到局部性原理,后面文章會進行介紹)。

緩存一致性

在單核CPU情況下,上述方法可以正常工作,可以確保緩存到CPU緩存中的數(shù)據(jù)永遠是“干凈”的,因為不會有其他CPU去更改內(nèi)存中的數(shù)據(jù),但是在多核CPU下,情況就變得更加復雜一些。多CPU中,每個CPU都有自己的私有緩存(可能共享L3緩存),當一個CPU1對Cache中緩存數(shù)據(jù)進行操作時,如果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 只有本地一個拷貝(專有);
  • E(專有,Exclusive):緩存行內(nèi)容和內(nèi)存中的一樣,而且其它處理器都沒有這行數(shù)據(jù);
  • S(共享,Shared):緩存行內(nèi)容和內(nèi)存中的一樣, 有可能其它處理器也存在此緩存行的拷貝;
  • I(無效,Invalid):緩存行失效, 不能使用。

每個CPU緩存行都在四個狀態(tài)之間互相轉(zhuǎn)換,以此決定CPU緩存是否失效,比如CPU1對一個緩存行執(zhí)行了寫入操作,則此操作會導致其他CPU的該緩存行進入Invalid無效狀態(tài),CPU需要使用該緩存行的時候需要從內(nèi)存中重新讀取。由此就解決了多CPU之間的緩存一致性問題。

偽共享

何謂偽共享?上面我們提過CPU的緩存是以緩存行為單位進行的,即除了本身所需讀寫的數(shù)據(jù)之外還會緩存與該數(shù)據(jù)在同一緩存行的數(shù)據(jù),假設(shè)緩存行大小是32字節(jié),內(nèi)存中有“abcdefgh”八個int型數(shù)據(jù),當CPU讀取“d”這個數(shù)據(jù)時,CPU會將“abcdefgh”八個int數(shù)據(jù)組成一個緩存行加入到CPU緩存中。假設(shè)計算機有兩個CPU:CPU1和CPU2,CPU1只對“a”這個數(shù)據(jù)進行頻繁讀寫,CPU2只對“b”這個數(shù)據(jù)進行頻繁讀寫,按理說這兩個CPU讀寫數(shù)據(jù)沒有任何關(guān)聯(lián),也就不會產(chǎn)生任何競爭,不會有性能問題,但是由于CPU緩存是以緩存行為單位進行存取的,也是以緩存行為單位失效的,即使CPU1只更改了緩存行中“a”數(shù)據(jù),也會導致CPU2中該緩存行完全失效,同理,CPU2對“b”的改動也會導致CPU1中該緩存行失效,由此引發(fā)了該緩存行在兩個CPU之間“乒乓”,緩存行頻繁失效,最終導致程序性能下降,這就是偽共享。

如何避免偽共享

避免偽共享主要有以下兩種方式:

1.緩存行填充(Padding):為了避免偽共享就需要將可能造成偽共享的多個變量處于不同的緩存行中,可以采用在變量后面填充字節(jié)的方式達到該目的。

2.使用某些語言或編譯器中強制變量對齊,將變量都對齊到緩存行大小,避免偽共享發(fā)生。

總結(jié)

一般偽共享都很隱蔽,很難被發(fā)現(xiàn),當偽共享真正構(gòu)成性能瓶頸的時候,我們有必要去努力找到并解決它,但是在大部分對性能追求沒有那么高的應(yīng)用中,偽共享的存在對程序的危害很小,有時并不值得耗費精力和額外的內(nèi)存空間(緩存行填充)去查找系統(tǒng)存在的偽共享。還是那句我一直以來遵循的話“不要過度優(yōu)化,不要提前優(yōu)化?!薄?/p>

以上就是淺談C++性能榨汁機之偽共享的詳細內(nèi)容,更多關(guān)于C++性能榨汁機之偽共享的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • c++中的const_cast用法大全

    c++中的const_cast用法大全

    const_cast轉(zhuǎn)換符是用來移除變量的const或volatile限定符。對于后者,我不是太清楚,因為它涉及到了多線程的設(shè)計,今天重點給大家介紹c++中的const_cast用法大全,需要的朋友參考下吧
    2021-07-07
  • C++ 智能指針使用不當導致內(nèi)存泄漏問題解析

    C++ 智能指針使用不當導致內(nèi)存泄漏問題解析

    這篇文章主要介紹了C++ 智能指針使用不當導致內(nèi)存泄漏問題解析,本文通過代碼示例給大家介紹的非常詳細,感興趣的朋友跟隨小編一起看看吧
    2024-07-07
  • C++實現(xiàn)數(shù)字轉(zhuǎn)換為十六進制字符串的方法

    C++實現(xiàn)數(shù)字轉(zhuǎn)換為十六進制字符串的方法

    這篇文章主要介紹了C++實現(xiàn)數(shù)字轉(zhuǎn)換為十六進制字符串的方法,涉及C++操作數(shù)字與字符串轉(zhuǎn)換的相關(guān)技巧,需要的朋友可以參考下
    2015-06-06
  • C語言的變量類型及內(nèi)存大小詳解

    C語言的變量類型及內(nèi)存大小詳解

    這篇文章主要介紹了CC和C++變量類型及內(nèi)存大小,是C++入門學習中的基礎(chǔ)知識,需要的朋友可以參考下,希望能夠給你帶來幫助
    2021-09-09
  • uboot添加自定義命令的實現(xiàn)步驟

    uboot添加自定義命令的實現(xiàn)步驟

    uboot 屬于bootloader的一種,是用來引導啟動內(nèi)核的,它的最終目的就是從flash中讀出內(nèi)核,放到內(nèi)存中,啟動內(nèi)核,這篇文章主要介紹了uboot添加自定義命令的實現(xiàn)步驟,需要的朋友可以參考下
    2022-11-11
  • C語言實現(xiàn)txt數(shù)據(jù)讀入內(nèi)存/CPU緩存實例詳解

    C語言實現(xiàn)txt數(shù)據(jù)讀入內(nèi)存/CPU緩存實例詳解

    這篇文章主要介紹了C語言實現(xiàn)txt數(shù)據(jù)讀入內(nèi)存/CPU緩存實例詳解的相關(guān)資料,這里對實現(xiàn)該函數(shù)進行了代碼實現(xiàn),需要的朋友可以參考下
    2017-01-01
  • 利用C語言玩轉(zhuǎn)魔方陣實例教程

    利用C語言玩轉(zhuǎn)魔方陣實例教程

    這篇文章主要給大家介紹了關(guān)于利用C語言玩轉(zhuǎn)魔方陣的相關(guān)資料,文中詳細介紹了關(guān)于奇數(shù)魔方陣和4N 魔方陣的實現(xiàn)方法,通過示例代碼讓大家更好的參考學習,需要的朋友們下面隨著小編來一起學習學習吧。
    2017-11-11
  • C++實現(xiàn)字符串刪除字符后逆序輸出

    C++實現(xiàn)字符串刪除字符后逆序輸出

    這篇文章主要為大家詳細介紹了C++實現(xiàn)字符串刪除字符后逆序輸出,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-05-05
  • VC創(chuàng)建圓角dialog的實現(xiàn)方法

    VC創(chuàng)建圓角dialog的實現(xiàn)方法

    這篇文章主要介紹了VC創(chuàng)建圓角dialog的實現(xiàn)方法,結(jié)合實例形式分析了圓角dialog對話框的創(chuàng)建步驟與相關(guān)操作技巧,需要的朋友可以參考下
    2016-08-08
  • C++ Qt開發(fā)之使用QProcess實現(xiàn)進程管理

    C++ Qt開發(fā)之使用QProcess實現(xiàn)進程管理

    Qt 是一個跨平臺C++圖形界面開發(fā)庫,利用Qt可以快速開發(fā)跨平臺窗體應(yīng)用程序,本文將重點介紹如何運用QProcess組件實現(xiàn)針對進程的控制管理等,感興趣的可以了解下
    2024-03-03

最新評論

华容县| 珲春市| 泰兴市| 称多县| 六枝特区| 胶南市| 车险| 禹州市| 岗巴县| 敦化市| 诸暨市| 昌平区| 驻马店市| 林口县| 阜新市| 瑞安市| 仙居县| 嘉兴市| 绥滨县| 林甸县| 富川| 新干县| 水富县| 连城县| 清流县| 博爱县| 辽中县| 青田县| 元朗区| 双柏县| 蒙城县| 临潭县| 若尔盖县| 浮梁县| 盐城市| 闻喜县| 神池县| 高要市| 通辽市| 通海县| 繁峙县|