【計算機體系結構】緩存的false sharing

在介紹緩存的false sharing之前,本文先介紹一下多核系統中緩存一致性是如何維護的。
目前主流的多核系統中的緩存一致性協議是MESI協議及其衍生協議。

MESI協議

MESI協議的4種狀態

MESI協議有4種狀態。MESI是4種狀態的首字母縮寫,緩存行的4種狀態分別如下。
(1)修改(Modified):表示數據只在本處理器的緩存中存在副本,數據是的,即數據被修改過,沒有寫回到內存。
(2)獨占(Exclusive):表示數據只在本處理器的緩存中存在副本,數據是干凈的,即副本和內存中的數據相同。
(3)共享(Shared):表示數據可能在多個處理器的緩存中存在副本,數據是干凈的,即所有副本和內存中的數據相同。
(4)無效(Invalid):表示緩存行中沒有存放數據。

MESI協議的消息

為了維護緩存一致性,處理器之間需要通信,MESI協議提供了以下消息。
(1)讀(Read):包含想要讀取的緩存行的物理地址。
(2)讀響應(Read Response):包含讀消息請求的數據。讀響應消息可能是由內存控制器發送的,也可能是由其他處理器的緩存發送的。如果一個處理器的緩存有想要的數據,并且處于修改狀態,那么必須發送讀響應消息
(3)使無效(Invalidate):包含想要刪除的緩存行的物理地址。所有其他處理器必須從緩存中刪除對應的數據,并且發送使無效確認消息來應答。
(4)使無效確認(Invalidate Acknowledge):處理器收到使無效消息,必須從緩存中刪除對應的數據,并且發送使無效確認消息來應答。
(5)讀并且使無效(Read Invalidate):包含想要讀取的緩存行的物理地址,同時要求從其他緩存中刪除數據。它是讀消息和使無效消息的組合,需要接收者發送讀響應消息和使無效確認消息。
(6)寫回(Writeback):包含想要寫回到內存的地址和數據。

MESI協議的狀態轉換

緩存行狀態的轉換如下圖所示。
在這里插入圖片描述
(1)轉換a,修改M到獨占E:處理器收到寫回消息,把緩存行寫回內存,但是緩存行保留數據。
(2)轉換b,獨占E到修改M:處理器寫數據到緩存行。
(3)轉換c,修改M到無效I:處理器收到“讀并且使無效”消息,發送讀響應消息和使無效確認消息,刪除本地副本(不需要寫回內存,因為發送“讀并且使無效”消息的處理器需要寫數據)。
(4)轉換d,無效I到修改M:處理器寫不在本地緩存中的數據,發送“讀并且使無效”消息,通過讀響應消息收到數據。處理器可以在收到所有其他處理器的使無效確認消息以后轉換到修改狀態M
(5)轉換e,共享S到修改M:處理器寫數據,該數據在緩存中命中,則只需發送使無效消息,收到所有其他處理器的使無效確認消息以后轉換到修改狀態M
(6)轉換f,修改M到共享S:其他處理器讀取緩存行,發送讀消息,本處理器收到讀消息后,寫回內存,保留一個只讀副本,發送讀響應消息
(7)轉換g,獨占E到共享S:其他處理器讀取緩存行,發送讀消息,本處理器收到后發送讀響應消息,保留一個只讀副本。
(8)轉換h,共享S到獨占E:本處理器意識到很快需要寫數據,發送使無效消息,收到所有其他處理器的使無效確認消息以后轉換到獨占狀態E。
(9)轉換i,獨占E到無效I:其他處理器寫數據,發送“讀并且使無效”消息,本處理器收到消息后,發送讀響應消息使無效確認消息
(10)轉換j,無效I到獨占E:處理器寫不在本地緩存中的數據,發送“讀并且使無效”消息,收到讀響應消息和所有其他處理器的使無效確認消息后轉換到獨占狀態E,完成寫操作后轉換到修改狀態M
(11)轉換k,無效I到共享S:處理器加載不在本地緩存中的數據,發送讀消息,收到讀響應消息后轉換到共享狀態S
(12)轉換l,共享S到無效I:其他處理器寫本地緩存中的數據,發送使無效消息,本處理器收到后,把緩存行的狀態轉換為無效,發送使無效確認消息

false sharing偽共享

false sharing概念

定義:當多線程修改互相獨立的變量時,如果這些變量共享同一個緩存行,就會無意中影響彼此的性能,這就是偽共享
Cache和內存之間交換數據的最小粒度不是字節,而是稱為cache line的一塊固定大小的區域,緩存行是內存交換的實際單位。緩存行是2的整數冪個連續字節,一般為32~256個字節,最常見的緩存行大小是64個字節。
在寫多線程代碼時,為了避免使用鎖,通常會采用這樣的數據結構:根據線程的數目,安排一個數組, 每個線程一個項,互相不沖突。從邏輯上看這樣的設計無懈可擊,但是實踐的過程可能會發現有些場景下非但沒提高執行速度,反而性能會很差。
問題在于cpu的Cache Line,當多線程修改互相獨立的變量時,如果這些變量共享同一個緩存行,就會無意中影響彼此的性能,這就是偽共享,即false-sharing
例如,在Intel Core 2 Duo處理器平臺上,L2 cache是由兩個core共享的,而L1 data cache是分開的,由兩個core分別存取。cache line的大小是64 Bytes。假設有個全局共享結構體變量f由2個線程A和B共享讀寫,該結構體一共8個字節同時位于同一條cache line上。

struct foo {int x;int y;
};

若此時兩個線程一個讀取f.x另一個讀取f.y,即便兩個線程的執行是在獨立的cpu core上的,實際上結構體對象f被分別讀入到兩個CPUs的cache line中且該cache line 處于shared狀態。若此時在核心1上運行的線程A想更新變量X,同時核心2上的線程B想要更新變量Y,則:
如果核心1上線程A優先獲得了所有權,線程A修改f.x會使該CPU core 1上的這條cache line將變為modified狀態,另一個CPU core 2上對應的cache line將變成invalid狀態;此時若線程B馬上讀取f.y,為了確保cache一致性,B所在CPU核上的相應cache line的數據必須被更新;當核心2上線程B優先獲得了所有權然后執行更新操作,核心1就要使自己對應的緩存行失效。這會來來回回的經過L3緩存,影響性能。如果互相競爭的核心位于不同的插槽,就要額外橫跨插槽連接,若讀寫的次數頻繁,將增大cache miss的次數,嚴重影響系統性能。
雖然在memory的角度這兩種訪問是隔離的,但是由于錯誤的緊湊地放在了一起,使得兩個變量處于同一個緩存行中。每個線程都要去競爭緩存行的所有權來更新變量。可見,false sharing會導致多核處理器上對于緩存行Cache Line的寫競爭,造成嚴重的系統性能下降,有人將偽共享描述成無聲的性能殺手,因為從代碼中很難看清楚是否會出現偽共享。

false-sharing避免方法

把每個項湊齊Cache Line的長度,即可實現隔離,雖然這不可避免的會浪費一些內存。

  • 對于共享數組而言,增大數組元素的間隔使得由不同線程存取的數組元素位于不同的Cache Line上,使一個核上的Cache line修改不會影響其它核;或者在每個線程中創建全局數組的本地拷貝,然后執行結束后再寫回全局數組,此方法比較粗暴不優雅。
  • 對于共享結構體而言,使每個結構體成員變量按照Cache Line大小(一般64B)對齊。可能需要使用#pragma宏。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/39048.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/39048.shtml
英文地址,請注明出處:http://en.pswp.cn/web/39048.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【Linux】—Xshell、Xftp安裝

文章目錄 前言一、下載Xshell、Xftp二、安裝Xshell三、使用XShell連接Linux服務器四、修改windows的主機映射文件(hosts文件)五、遠程連接hadoop102/hadoop103/hadoop104服務器六、安裝Xftp 前言 XShell遠程管理工具,可以在Windows界面下來訪…

[數據集][目標檢測]螺絲螺母檢測數據集VOC+YOLO格式2400張2類別

數據集格式:Pascal VOC格式YOLO格式(不包含分割路徑的txt文件,僅僅包含jpg圖片以及對應的VOC格式xml文件和yolo格式txt文件) 圖片數量(jpg文件個數):2400 標注數量(xml文件個數):2400 標注數量(txt文件個數):2400 標注…

SpringBoot 整合 Minio 實現文件切片極速上傳技術

Centos7安裝Minio 創建目標文件夾 mkdir minio使用docker查看目標鏡像狀況 大家需要注意,此處我們首先需要安裝docker,對于相關安裝教程,大家可以查看我之前的文章,按部就班就可以,此處不再贅述!&#x…

uniapp入門

一、新建項目 進入到主界面,左上角點擊新建——1.項目 輸入項目名稱,Vue版本選擇3 二、創建頁面 選中左側文件目錄里的pages文件夾,右鍵,選擇新建頁面 1輸入名稱 2選中“創建同名目錄” 3選擇模板&…

將json對象轉為xml進行操作屬性

將json對象轉為xml進行操作屬性 文章目錄 將json對象轉為xml進行操作屬性前端發送json數據格式寫入數據庫格式-content字段存儲(varchar(2000))Question實體類-接口映射對象QuestionContent 接收參數對象DAO持久層Mapper層Service層Controller控制層接收…

《每天5分鐘用Flask搭建一個管理系統》第13章:性能優化

第13章:性能優化 13.1 性能優化的重要性 性能優化確保應用能夠處理高并發請求,減少響應時間,提高用戶體驗和應用的可擴展性。 13.2 Flask緩存機制 緩存是提高Web應用性能的關鍵技術之一,它可以減少數據庫查詢次數和服務器計算…

Java 開發環境配置

配置Java開發環境涉及幾個主要步驟,包括安裝Java Development Kit (JDK)、配置環境變量和選擇集成開發環境(IDE)。以下是詳細的配置步驟: ### 1. 安裝 Java Development Kit (JDK) 1. **下載 JDK**: 訪問 Oracle …

完全指南:在Linux上安裝和精通Conda

前言 Conda是一個強大的包管理和環境管理工具,特別適用于數據科學和機器學習項目。本文將詳細指導你在Linux系統上安裝、配置和充分利用Conda的方法。 步驟一:下載和安裝Conda 下載安裝包: wget https://repo.anaconda.com/miniconda/Minic…

普元EOS學習筆記-低開實現圖書的增刪改查

前言 在前一篇《普元EOS學習筆記-創建精簡應用》中,我已經創建了EOS精簡應用。 我之前說過,EOS精簡應用就是自己創建的EOS精簡版,該項目中,開發者可以進行低代碼開發,也可以進行高代碼開發。 本文我就記錄一下自己在…

Golang中swtich中如何強制執行下一個代碼塊

switch 語句中的 case 代碼塊會默認帶上 break,但可以使用 fallthrough 來強制執行下一個 case 代碼塊。 package mainimport ("fmt" )func main() {isSpace : func(char byte) bool {switch char {case : // 空格符會直接 break,返回 false…

2024年6月 | deepin 深度應用商店-應用更新記錄

新增應用 序號應用名稱depein 系統版本應用分類應用類型1bkViewer 照片瀏覽器deepin 20.9 deepin V23網絡應用wine291助手deepin 20.9 deepin V23編程開發wine3風云CAD轉換器deepin 20.9 deepin V23編程開發wine4Disk Savvydeepin 20.9 deepin V23系統工具wine5飛貓盤…

miniconda3 安裝jupyter notebook并配置網絡訪問

由于服務器安裝的miniconda3,無jupyter notebook,所以手工安裝jupyter notebook 1 先conda 安裝相關包 在base 環境下 conda install ipython conda install jupyter notebook 2 生成配置文件 jupyter notebook --generate-config Writing defaul…

Nginx 常用配置與應用

Nginx 常用配置與應用 官網地址:https://nginx.org/en/docs/ 目錄 Nginx 常用配置與應用 Nginx總架構 正向代理 反向代理 Nginx 基本配置反向代理案例 負載均衡 Nginx總架構 進程模型 正向代理 反向代理 Nginx 基本配置反向代理案例 負載均衡 Nginx 基本配置…

新人程序員接手丑陋的老代碼怎么辦?改還是不改......

許多小伙伴在初入職場的時候,都會遇到要接手老代碼的情況,那么問題來了,如果老代碼十分丑陋,你是改還是不改? 不改吧,心里難受;改吧,指不定會遇到什么情況,比如…… 1.…

【嫦娥四號】月球著陸器中子和劑量測量(LND)實驗

一、引言 嫦娥四號任務是中國月球探測計劃的重要里程碑,實現了人類首次在月球背面軟著陸,并展開了月面巡視和中繼通信。本文所描述的嫦娥四號著陸器上的中子與劑量測定實驗(Lunar Lander Neutrons and Dosimetry Experiment, LND&#xff09…

【雷豐陽-谷粒商城 】【分布式高級篇-微服務架構篇】【17】認證服務01

持續學習&持續更新中… 守破離 【雷豐陽-谷粒商城 】【分布式高級篇-微服務架構篇】【17】認證服務01 環境搭建驗證碼倒計時短信服務郵件服務驗證碼短信形式:郵件形式: 異常機制MD5參考 環境搭建 C:\Windows\System32\drivers\etc\hosts 192.168.…

嵌入式PCB制圖面試題及參考答案(2萬字長文)

目錄 如何設計適用于RF(射頻)應用的PCB? 介紹柔性PCB設計的基本考慮因素。 在高電壓PCB設計中,如何確保安全距離? 何為埋盲孔技術?在哪些應用中會用到? PCB設計項目管理的關鍵要素有哪些? 如何有效地與硬件工程師、機械工程師協同工作? 介紹一種提高設計審查效…

JAVA每日作業day7.1-7.3小總結

ok了家人們前幾天學了一些知識,接下來一起看看吧 一.API Java 的 API ( API: Application( 應用 ) Programming( 程序 ) Interface(接口 ) ) Java API 就是 JDK 中提供給我們使用的類,這些類將底層 的代碼實現封裝了起來&#x…

編寫高效的Java工具類:實用技巧與設計模式

編寫高效的Java工具類:實用技巧與設計模式 大家好,我是免費搭建查券返利機器人省錢賺傭金就用微賺淘客系統3.0的小編,也是冬天不穿秋褲,天冷也要風度的程序猿! 1. 工具類的定義與作用 在軟件開發中,工具…

【echarts】拖拽滑塊dataZoom-slider自定義樣式,簡單適配移動端

電腦端 移動端 代碼片段 dataZoom: [{type: inside,start: 0,end: 100},{type: slider,backgroundColor: #F2F5F9,fillerColor: #BFCCE3,height: 13, // 設置slider的高度為15start: 0,end: 100,right: 60,left: 60,bottom: 15,handleIcon:path://M30.9,53.2C16.8,53.2,5.3,41.…