主頁 > 軟體設計 > 記憶體屏障到底要解決什么問題?

記憶體屏障到底要解決什么問題?

2022-03-28 23:29:06 軟體設計

我現在正試圖解決記憶障礙的問題。我一直在閱讀和觀看有關該主題的視頻,我想確保自己理解正確,并提出一兩個問題。

我從準確理解問題開始。讓我們以以下經典示例作為討論的基礎:假設我們有 2 個執行緒在 2 個不同的內核上運行

這是偽代碼!

我們從這些執行緒開始,int f = 0; int x = 0;然后運行:

# Thread 1

while(f == 0);

print(x)
# Thread 2 

x = 42;
f = 1;

當然,這個程式想要的結果是執行緒 1 將列印 42。

注意:我不討論“編譯時重新排序”,我只想關注運行時發生的事情,所以忽略編譯器可能做的各種優化。

好的,據我了解,這里的問題是所謂的“記憶體重新排序”:只要最終結果是程式所期望的,CPU 就可以自由地重新排序記憶體操作。在這種情況下,在執行緒 2 中,f = 1可能會在x = 42. 在這種情況下,執行緒 1 將列印 0,這不是程式員想要的。

此時,維基百科指出了另一種可能發生的情況:

類似地,執行緒#1 的加載操作可能會亂序執行,并且有可能在檢查 f 之前讀取 x

由于我們現在談論的是“亂序執行”——讓我們暫時忽略內核快取。那么讓我們來分析一下這里發生了什么。從執行緒 2 開始 - 編譯后的指令看起來(在偽匯編中)類似于:

1 put 42 into register1
2 write register1 to memory location of x
3 put 1 into register 2
4 write register2 to memory location of f

Ok so I understand that 3-4 may be executed before 1-2. But I don't understand the equivalent in thread 1:

Let's say the instructions of thread 1 will be something like:

1 load f to register1
2 if f is 0 - jump to 1
3 load x to register2
4 print register2

What exactly may be out of order here? 3 can be before 1-2?

Let's go on: Up until now we talked about out-of-order execution, which brings me to my primary confusion:

In this great post the author describes the problem as such: Each core has its own cache, and the core does the memory operations against the cache, not against the main memory. The movement of memory from the core-specific caches to the main memory (or a shared cache) occurs in unpredictable time and order. So in our example - even if thread 2 will execute its instructions in-order - the writing of x=42 will occur before f=1, but that will be only to the cache of core2. The movement of these values to a shared memory may be in the opposite order, and hence the problem.

So I don't understand - when we talk about "memory reordering" - do we talk about Out-of-order execution, or are we talking about the movement of data across caches?

uj5u.com熱心網友回復:

當我們談論“記憶體重新排序”時——我們是在談論亂序執行,還是在談論跨快取的資料移動?

當執行緒以特定順序觀察值的變化時,從程式員的角度來看,無法區分這是否是由于加載的無序執行、存盤緩沖區相對于加載延遲存盤并可能讓它們無序提交(無論執行順序如何),或(假設在沒有一致快取的 CPU 中)快取同步。

或者甚至通過在邏輯核心之間轉發存盤資料而不通過快取,在它提交到快取并變得對所有核心可見之前。 一些 POWER CPU 在現實生活中可以做到這一點,但很少有其他的。

真正的 CPU 具有一致的快取一旦一個值提交到快取,它對所有內核都是可見的;在其他副本已經失效之前它不會發生,因此這不是讀取“陳舊”資料的機制。現實世界 CPU 上的記憶體重新排序是發生在內核中的事情,連貫快取的讀取和寫入可能以與程式順序不同的順序發生。快取不同步后不會重新同步;它首先保持一致性。

無論機制如何,重要的影響是另一個執行緒觀察您正在讀取/寫入的相同變數,可以看到效果以與匯編程式順序不同的順序發生。

uj5u.com熱心網友回復:

您的兩個郵件問題都有相同的答案(是的!),但原因不同。

首先讓我們看一下這段特殊的偽機器代碼

假設執行緒 1 的指令類似于:

1 load f to register1
2 if f is 0 - jump to 1
3 load x to register2
4 print register2

這里到底有什么問題?3可以在1-2之前嗎?

要回答您的問題,這是一個回蕩的“是!”。由于 的內容與 CPUregister1的內容沒有任何關聯,因此register2可以愉快地(并且正確地) preload register2,因此當 1,2 回圈最終中斷時,它可以立即轉到 4。

舉一個實際的例子,register1可能是一個連接到輪詢串行時鐘的 I/O 外設暫存器,而 CPU 只是等待時鐘轉換為低電平,以便它可以將下一個值按位發送到資料輸出線上。這樣做可以節省資料獲取的寶貴時間,更重要的是可以避免外圍資料總線上的爭用。

所以,是的,這種重新排序是非常好的并且是允許的,即使優化關閉發生在單執行緒、單核 CPU 上。在回圈中斷后,確保register2絕對讀取的唯一方法是插入屏障。

第二個問題是關于快取一致性的。再一次,需要記憶體屏障的答案是“是的!你需要它們”。快取一致性是一個問題,因為現代 CPU 不直接與系統記憶體通信,而是通過它們的快取。只要您只處理單個 CPU 內核和單個快取,一致性就不是問題,因為在同一個內核上運行的所有執行緒都針對同一個快取作業。但是,當您擁有多個具有獨立快取的內核時,它們對系統記憶體內容的各個視圖可能會有所不同,并且需要某種形式的記憶體一致性模型。通過顯式插入記憶體屏障,或在硬體級別上。

uj5u.com熱心網友回復:

在我看來,你錯過了最重要的事情!

由于編譯器沒有看到該更改x也沒有f任何副作用,因此編譯器也可以將所有這些優化掉。并且帶有條件的回圈也f==0將導致“無”,因為編譯器只看到您f=0之前傳播了一個常量,它可以假設這f==0將始終為真并將其優化掉。

對于所有這些,你必須告訴編譯器將會發生一些從給定的代碼流中看不到的事情。這可能類似于呼叫某些信號量/互斥量/...或其他 IPC 功能或使用atomicvars。

如果你編譯你的代碼,我假設你或多或少地得到“沒有”,因為對于兩個代碼部分中的每一個都沒有任何影響,并且編譯器沒有看到變數是從兩個執行緒背景關系中使用的并且優化了所有的東西。

如果我們按照以下示例實作代碼,我們會看到它失敗并0在我的系統上列印。

int main()
{
    int f = 0; 
    int x = 0; 

    std::thread s( [&f,&x](){ x=42; f=1; } ); 

    while( f==0);
    std::cout << x << std::endl;

    s.join();
}

如果我們更改int f = 0;為,std::atomic<int> f = 0我們會得到預期的結果。

轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/450947.html

標籤:c assembly memory-barriers instructions

上一篇:MongooseError:操作`x.findOne()`緩沖在10000毫秒后超時

下一篇:錯誤的基準,令人費解的組裝

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 面試突擊第一季,第二季,第三季

    第一季必考 https://www.bilibili.com/video/BV1FE411y79Y?from=search&seid=15921726601957489746 第二季分布式 https://www.bilibili.com/video/BV13f4y127ee/?spm_id_fro ......

    uj5u.com 2020-09-10 05:35:24 more
  • 第三單元作業總結

    1.前言 這應該是本學期最后一次寫作業總結了吧。總體來說,對作業的節奏也差不多掌握了,作業做起來的效率也更高了。雖然和之前的作業一樣,作業中都要用到新的知識,但是相比之前,更加懂得了如何利用工具以及資料。雖然之間卡過殼,但總體而言,這幾次作業還算完成的比較好。 2.作業程序總結 相比前兩個單元,此單 ......

    uj5u.com 2020-09-10 05:35:41 more
  • 北航OO(2020)第四單元博客作業暨課程總結博客

    北航OO(2020)第四單元博客作業暨課程總結博客 本單元作業的架構設計 在本單元中,由于UML圖具有比較清晰的樹形結構,因此我對其中需要進行查詢操作的元素進行了包裝,在樹的父節點中存盤所有孩子的參考。考慮到性能問題,我采用了快取機制,一次查詢后盡可能快取已經遍歷過的資訊,以減少遍歷次數。 本單元我 ......

    uj5u.com 2020-09-10 05:35:48 more
  • BUAA_OO_第四單元

    一、UML決議器設計 ? 先看下題目:第四單元實作一個基于JDK 8帶有效性檢查的UML(Unified Modeling Language)類圖,順序圖,狀態圖分析器 MyUmlInteraction,實際上我們要建立一個有向圖模型,UML中的物件(元素)可能與同級元素連接,也可與低級元素相連形成 ......

    uj5u.com 2020-09-10 05:35:54 more
  • 6.1邏輯運算子

    邏輯運算子 1. && 短路與 運算式1 && 運算式2 01.運算式1為true并且運算式2也為true 整體回傳為true 02.運算式1為false,將不會執行運算式2 整體回傳為false 03.只要有一個運算式為false 整體回傳為false 2. || 短路或 運算式1 || 運算式2 ......

    uj5u.com 2020-09-10 05:35:56 more
  • BUAAOO 第四單元 & 課程總結

    1. 第四單元:StarUml檔案決議 本單元采用了圖模型決議UML。 UML檔案可以抽象為圖、子圖、邊的邏輯結構。 在實作中,圖的節點包括類、介面、屬性,子圖包括狀態圖、順序圖等。 采用了三次遍歷UML元素的方法建圖,第一遍遍歷建點,第二、三次遍歷設定屬性、連邊,實作圖物件的初始化。這里借鑒了一些 ......

    uj5u.com 2020-09-10 05:36:06 more
  • 談談我對C# 多型的理解

    面向物件三要素:封裝、繼承、多型。 封裝和繼承,這兩個比較好理解,但要理解多型的話,可就稍微有點難度了。今天,我們就來講講多型的理解。 我們應該經常會看到面試題目:請談談對多型的理解。 其實呢,多型非常簡單,就一句話:呼叫同一種方法產生了不同的結果。 具體實作方式有三種。 一、多載 多載很簡單。 p ......

    uj5u.com 2020-09-10 05:36:09 more
  • Python 資料驅動工具:DDT

    背景 python 的unittest 沒有自帶資料驅動功能。 所以如果使用unittest,同時又想使用資料驅動,那么就可以使用DDT來完成。 DDT是 “Data-Driven Tests”的縮寫。 資料:http://ddt.readthedocs.io/en/latest/ 使用方法 dd. ......

    uj5u.com 2020-09-10 05:36:13 more
  • Python里面的xlrd模塊詳解

    那我就一下面積個問題對xlrd模塊進行學習一下: 1.什么是xlrd模塊? 2.為什么使用xlrd模塊? 3.怎樣使用xlrd模塊? 1.什么是xlrd模塊? ?python操作excel主要用到xlrd和xlwt這兩個庫,即xlrd是讀excel,xlwt是寫excel的庫。 今天就先來說一下xl ......

    uj5u.com 2020-09-10 05:36:28 more
  • 當我們創建HashMap時,底層到底做了什么?

    jdk1.7中的底層實作程序(底層基于陣列+鏈表) 在我們new HashMap()時,底層創建了默認長度為16的一維陣列Entry[ ] table。當我們呼叫map.put(key1,value1)方法向HashMap里添加資料的時候: 首先,呼叫key1所在類的hashCode()計算key1 ......

    uj5u.com 2020-09-10 05:36:38 more
最新发布
  • 【中介者設計模式詳解】C/Java/JS/Go/Python/TS不同語言實作

    * 中介者模式是一種行為型設計模式,它可以用來減少類之間的直接依賴關系,
    * 將物件之間的通信封裝到一個中介者物件中,從而使得各個物件之間的關系更加松散。
    * 在中介者模式中,物件之間不再直接相互互動,而是通過中介者來中轉訊息。 ......

    uj5u.com 2023-04-20 08:20:47 more
  • 露天煤礦現場調研和交流案例分享

    他們集團的資訊化公司及研究院在一個礦區正在做智能礦山的統一平臺的 試點,專案投資大概1億,包括了礦山的各方面的內容,顯示得我們這次交流有點多余。他們2年前開始做智能礦山的規劃,有很多煤礦行業專家的加持,他們的描述是非常完美,但是去年底應該上線的平臺,現在還沒有看到影子。他們確實有很多場景需求,但是被... ......

    uj5u.com 2023-04-20 08:20:25 more
  • 《社區人員管理》實戰案例設計&個人案例分享

    設計是一個讓人夢想成真程序,開始編碼、測驗、除錯之前進行需求分析和架構設計,才能保證關鍵方面都做正確 ......

    uj5u.com 2023-04-20 08:20:17 more
  • 軟體架構生態化-多角色交付的探索實踐

    作為一個技術架構師,不僅僅要緊跟行業技術趨勢,還要結合研發團隊現狀及痛點,探索新的交付方案。在日常中,你是否遇到如下問題 “ 業務需求排期長研發是瓶頸;非研發角色感受不到研發技改提效的變化;引入ISV 團隊又擔心質量和安全,培訓周期長“等等,基于此我們探索了一種新的技術體系及交付方案來解決如上問題。 ......

    uj5u.com 2023-04-20 08:20:10 more
  • 【中介者設計模式詳解】C/Java/JS/Go/Python/TS不同語言實作

    * 中介者模式是一種行為型設計模式,它可以用來減少類之間的直接依賴關系,
    * 將物件之間的通信封裝到一個中介者物件中,從而使得各個物件之間的關系更加松散。
    * 在中介者模式中,物件之間不再直接相互互動,而是通過中介者來中轉訊息。 ......

    uj5u.com 2023-04-20 08:19:44 more
  • 露天煤礦現場調研和交流案例分享

    他們集團的資訊化公司及研究院在一個礦區正在做智能礦山的統一平臺的 試點,專案投資大概1億,包括了礦山的各方面的內容,顯示得我們這次交流有點多余。他們2年前開始做智能礦山的規劃,有很多煤礦行業專家的加持,他們的描述是非常完美,但是去年底應該上線的平臺,現在還沒有看到影子。他們確實有很多場景需求,但是被... ......

    uj5u.com 2023-04-20 08:19:07 more
  • 《社區人員管理》實戰案例設計&個人案例分享

    設計是一個讓人夢想成真程序,開始編碼、測驗、除錯之前進行需求分析和架構設計,才能保證關鍵方面都做正確 ......

    uj5u.com 2023-04-20 08:18:57 more
  • 軟體架構生態化-多角色交付的探索實踐

    作為一個技術架構師,不僅僅要緊跟行業技術趨勢,還要結合研發團隊現狀及痛點,探索新的交付方案。在日常中,你是否遇到如下問題 “ 業務需求排期長研發是瓶頸;非研發角色感受不到研發技改提效的變化;引入ISV 團隊又擔心質量和安全,培訓周期長“等等,基于此我們探索了一種新的技術體系及交付方案來解決如上問題。 ......

    uj5u.com 2023-04-20 08:18:49 more
  • 05單件模式

    #經典的單件模式 public class Singleton { private static Singleton uniqueInstance; //一個靜態變數持有Singleton類的唯一實體。 // 其他有用的實體變數寫在這里 //構造器宣告為私有,只有Singleton可以實體化這個類! ......

    uj5u.com 2023-04-19 08:42:51 more
  • 【架構與設計】常見微服務分層架構的區別和落地實踐

    軟體工程的方方面面都遵循一個最基本的道理:沒有銀彈,架構分層模型更是如此,每一種都有各自優缺點,所以請根據不同的業務場景,并遵循簡單、可演進這兩個重要的架構原則選擇合適的架構分層模型即可。 ......

    uj5u.com 2023-04-19 08:42:41 more