鯤鵬開發重點-–扭轉x86乾坤的挑戰,ARM64內存模型

      網友投稿 1196 2022-05-29

      鯤鵬開發重點1–扭轉x86乾坤的挑戰,ARM64內存模型

      (老古、大何)

      一、前言:扭轉x86乾坤的挑戰

      1、ARM:超越x86二選一思維

      2、Apple:推出驚人速度的ARM筆記本電腦

      3、鯤鵬:扭轉x86乾坤的挑戰

      二、指令亂序執行:獨特架構的先進特性

      1、體系結構決定內存模型:X86強內存序,ARM64是弱內存序

      2、X86強內存序: 寫后讀亂,讀后讀/寫后寫/讀后寫不亂

      3、ARM64弱內存序: 精簡指令集把訪存指令和運算指令分開了

      三、并行流水:10000米高空的觀察

      1、ARM64:多個并行流水部件,支持超標量

      2、流水第一二階段:串并轉化、保亂皆有序

      3、避免事故最關鍵設計:不是完美匝道口,關鍵在于駕駛員

      4、安全距離是多少?如何預判?如何正確操作?

      5、觀察者PE/DMA:作為存放數據的內存位置,內部關系復雜

      6、低級語言、高級語言:合作、邊界

      四、ARMv8內存模型:全面的定義

      1、基本定義:Locations, Memory effects, and Observers

      2、位置(Location)

      3、內存影響(Memory effect):讀/寫/屏蔽

      5、觀察者(Observer):PE(Processing element)、代理

      6、普通共享域(Comman Shareability Domain)

      五、ARM64創新:排序及其可觀察性

      1、依賴約束、排序約束、APP序:OS和芯片協調邊界

      2、依賴:劃分界限,寄存器R,數值V和指令I

      3、基于位置的順序和可觀察性

      4、排序關系

      六、ARM64可控規則:系統中觀察者之間的交互

      1、使用共享變量來通信

      2、所有內存完成規則的定義

      3、外設

      七、附-參考資源:ARM?? Architecture Reference Manual

      ARM?? Architecture Reference Manual

      八、側記:像鯤鵬,去展翅高飛,共贏計算新時代

      (圖片來源于網絡)

      一、前言:扭轉x86乾坤的挑戰

      1、ARM:超越x86二選一思維

      ARM基礎設施事業部高級副總裁兼總經理Chris Bergey稱,ARM想改變行業對部署基礎設施的思維,每一個創新者都不應該被要求在性能與能耗之間進行抉擇,ARM平臺提供了兩者兼得的最佳解決方案。

      法國芯片公司SiPearl和韓國電子通信研究所( ETRI)的高性能計算(SoC)均可展現這些設計元素的優勢,這被ARM看作是高性能計算的發展方向

      ARM系列芯片之一Neoverse N2在安全性、能耗以及性能方面都有全面提升,并能為用戶減少TCO的每瓦性能表現。相比于Neoverse N1,N2在保持相同水平的功率和面積效率的基礎上,單線程性能提升了40%。

      ARM芯片具備良好的可擴展性,可以橫跨從高吞吐量計算到功率與尺寸受限的邊緣和5G應用場景,并在這些應用中帶來優于Neoverse N1的表現。例如,在云端上提升1.3倍的NGINX,在5G邊緣應用上提升1.2倍的DPDK數據包處理。

      2、Apple:推出驚人速度的ARM筆記本電腦

      今年還有一個里程碑式的事件,就是Apple以驚人的速度推出了基于ARM的筆記本電腦。Apple從來不是一個拘泥于現狀的公司,在其歷史上,就曾經在短時間內拋棄了摩托羅拉轉向Intel。但當時的情況是Powerpc日漸式微,而Intel明顯的處于快速上升期。如果告訴一個人說現在的iMac裝不了Win10了,有很大一批人可能都會猶豫。因此Apple當下的選擇好像是冒了很大的風險的。

      Apple與之不同之處在哪里呢,是有自己獨有的優勢,就是軟硬件一體的高度控制能力,這也是它敢于叫板Intel的底氣。由于IOS在龐大的電腦市場占比較小,目前還不能對X86構成什么威脅。但這次改變卻透露了X86未來可能的隱患,這就是基于Apple強有力的執行力和軟硬件整合力的推動下,在Apple體系中成功建立起移動、桌面和云的一體化,從而證明了ARM架構在泛云支持上的可能性。

      這個殺傷力就很大。

      這表明現在桌面和移動的幾乎所有應用都可以遷移到ARM上,同時對應的云端應用也可以用ARM支持,這樣相當于直接切入了X86全部的生態圈。

      3、鯤鵬:扭轉x86乾坤的挑戰

      因為X86及其CISC架構生態的封閉性,中國市場對未來處理器的選擇,將是更開放、更模塊化的RISC架構。

      鯤鵬處理器就是符合這個潮流的創新產品和生態,將直面一系列挑戰,和Apple一樣贏得這場挑戰,來扭轉X86的封閉性的乾坤,創造出中國的處理器新生態。

      因為鯤鵬采用ARM64架構,其RISC架構和x86的CISC架構有很大的不同,原來在x86處理器上運行健壯的程序,在ARM64上不穩定,開發人員隨口說,ARM64處理器有什么問題嗎?這個帽子扣的有些大,后來發現是自己代碼搞錯了,有個代碼分支沒有加鎖,這部分代碼還是新寫的,并沒有在x86上運行多久,只是問題沒有暴露而已。這是一個烏龍,讓ARM64處理器背了鍋。

      其實,應用程序很少看到ARM64處理器的架構細節,也很少能碰到處理器的問題。中間隔著操作系統和編譯器,處理器架構相關的工作都已經適配了,跨體系結構移植代碼的難度也沒有預想的那么大。不能因為對ARM64不了解,就談虎色變,問題還是問題,還是需要從問題本身出發,從現象到本質。

      鯤鵬處理器基于ARM64架構,追求極致能效比,與x86處理器相比的優勢更在于多核和亂序執行,在處理程序并行上也會遇到一些挑戰。

      全新構建一個生態本身,不是一帆風順的,鯤鵬產業必須舉著”補洞”的大旗,再困難也要往前沖,有些困難的挑戰卻不僅僅是錦上添花的事情,在ARM64上干成了,就不怕和x86比了。

      本文主要講一講扭轉X86封閉性的乾坤重大挑戰之一:ARM64的指令亂序。

      二、指令亂序執行:獨特架構的先進特性

      ARM以及芯片架構師都有共識,ARM64就是這樣的,是允許指令亂序執行的,這是出于性能的考慮,這是架構特性,不是漏洞。網傳蘋果最新的M1處理器的亂序窗口達到600條。

      但是,指令亂序的影響卻給系統可靠性帶來了風險,驅動模塊,基礎軟件和應用軟件都要做排查、設計優化。所以,這是鯤鵬生態各產品線切換到ARM64平臺上的軟件也要謹慎面對。

      1、體系結構決定內存模型:X86強內存序,ARM64是弱內存序

      為什么會有指令亂序,這確實是體系結構的內存模型決定的,并不是有人在忽悠我們。

      2、X86強內存序: 寫后讀亂,讀后讀/寫后寫/讀后寫不亂

      X86是強內存序模型,復雜指令集允許其運算指令本身支持內存訪問,并允許非依賴的寫后讀指令亂序,其它非依賴的讀后讀,寫后寫,和讀后寫的指令都不會發生亂序。

      3、ARM64弱內存序: 精簡指令集把訪存指令和運算指令分開了

      ARM64是弱內存序模型,因為精簡指令集把訪存指令和運算指令分開了,為了性能,必須允許幾乎所有的指令亂序,但前提是必須遵守依賴約束和排序約束,不影響程序的邏輯和正確性。

      所以,ARM64上沒有依賴關系的讀后讀,寫后寫,讀后寫,和寫后讀都是可以亂序執行的。

      這聽起來很匪夷所思,那程序代碼還能保證正確嗎? 搞不定的問題都可以扣上CPU亂序的帽子嗎?

      這其實呢,在指令亂序前還得知道編譯亂序,ARM64處理器并不是直接面對程序代碼的,而是面對機器代碼,或者說匯編指令。

      由高級語言編寫的程序,如C語言,首先通過編譯器的編譯轉換為匯編指令,編譯器會根據ARM64處理器的流水線特點,合理安排匯編指令的順序,目的是最大限度的發揮CPU流水的并行能力。這也沒有什么可怕的,編譯器一定會在保證程序正確性的情況下,合理調整匯編指令的順序。

      (圖片來源于網絡)

      特別的,在源代碼中內聯匯編指令時,這個外部額外插入的匯編指令,要告訴編譯器不要優化指令順序,需要使用“__asm__ __volatile__("": : :"memory") ”的編譯提示。編譯階段的亂序不是我們關注的重點,而且這部分極少出錯。我們仍然回到CPU的指令亂序特性上來。

      三、并行流水:10000米高空的觀察

      生活中,特別是高速路的道路設計和CPU的流水設計有一點相似之處。高速路設計了并行的行車道和超車道,是允許超車的,這樣可以保證高速路的高效通行和最大車流量。

      經常開車的同學,肯定會為高速路上在行車道或者超車道上龜速行車的小汽車大為光火,也許你超車時還不忘瞟一眼,確認一下是不是女司機,其實多數是新手男司機才這么霸道。

      1、ARM64:多個并行流水部件,支持超標量

      ARM64設計了多個并行的流水部件,支持超標量,可以一個指令周期分發多條指令,實現最大程度的指令并行。

      2、流水第一二階段:串并轉化、保亂皆有序

      流水的第一階段包括指令提取,譯碼和分發,這部分是保序的;

      一旦到流水的第二階段,執行指令流“串并轉化”后,指令一旦分發到不同的并行流水部件中,它們的執行順序就是亂序的了。有依賴的指令會放到同一個流水部件,先進先出方式排隊,防止亂序執行。

      關于流水線的設計是如何保證指令并行的正確性,詳細的微架構分析,cache一致性原理等以后解釋,此處直接跳過。

      (圖片來源于網絡)

      高速匝道口事故:A變道是否影響B正常行駛

      高速路上經常發生事故的地方是匝道口。當左側超車道上的車輛A往右側匝道橫向慢速變道,往往導致后方行車道上正常行駛的車輛B剎車不及,導致追尾碰撞。當然,如果此段高速路上只有車輛A,或者后面的車B根本看不到蹤影,或者車輛A占用的車道和車輛B行駛的道路不相關,那么車輛A怎么慢吞吞的變道都沒有關系。所以,發生事故的條件之一就是車輛A的變道是否影響到車輛B正常行駛。

      (圖片來源于網絡)

      3、避免事故最關鍵設計:不是完美匝道口,關鍵在于駕駛員

      上圖僅是一個匝道口示意,這樣的設計是否足夠完美,我們不是專業人員,不做判斷,僅作參考。避免事故最關鍵的不是匝道口的完美設計,關鍵在于駕駛員。

      4、安全距離是多少?如何預判?如何正確操作?

      避險之道包括后車與前車保持足夠安全的行車距離,后車對形勢的正確預判,緊急情況下的正確操作。而安全距離是多少?如何預判?如何正確操作?這些都是車輛駕駛員的技能和安全意識所決定,所以,坐新手的車會讓你提心吊膽,坐老司機的車就是放心。千萬不要用發生在自己身上的交通事故來積累駕駛經驗,這樣的代價太大,網上有高速安全行駛教學視頻,這里不再過多描述。

      5、觀察者PE/DMA:作為存放數據的內存位置,內部關系復雜

      ARM64的指令亂序造成的軟件問題與高速路上的匝道口事故有一點相似的地方,也需要了解交通參與者,交通設施,規則和應急措施。在一個CPU系統中,作為觀察者的PE或者DMA等模塊,作為存放數據的內存位置,他們之間的關系并不像C語言描述的那么簡單,內部關系復雜。

      ARM公司沒有提供視頻講解,但是有架構參考手冊,ARM? Architecture Reference Manual?(ARMv8, for ARMv8-A architecture profile)的B2.3章節詳細描述了內存模型,把指令亂序的相關細節作了比較細致的抽象描述。

      6、低級語言、高級語言:合作、邊界

      ARM手冊中定義了一些陌生的低級語言詞匯,主要還是圍繞處理核,寄存器,內存,并發,依賴,指令序,執行序,觀察序等等。高級語言定義了邏輯關系,編譯器定義了數據依賴,控制依賴和地址依賴等依賴關系,ARMv8架構定義了內存模型。邏輯依賴主要與應用程序有關,指令順序主要與編譯器有關,指令亂序和內存墻主要與CPU有關,最終都是系統相關。

      手冊中的描述有好多新詞匯,并不通用,用中文翻譯找不到類似“波音”這類比英文還美妙的詞匯,就仍然保持了原來的英文單詞。

      ARMv8手冊中的內存模型章節真不是一段“好劇本”,有些晦澀,“雖不明,但覺厲”。google翻譯也不給力,難免錯誤,更不能搞的通俗易懂,只希望碼農需要時,有這個“粗加工”的中文參考。如果覺得本文描述很繞,請回到下面這張圖片,也許會感覺舒適一點。

      (圖片來源于網絡)

      此文檔即不是編程規范,也不是編程軍規,并不需要所有碼農都了解,但是,驅動軟件相關,無鎖隊列相關和并發軟件相關的碼農需要稍加留意。

      四、ARMv8內存模型:全面的定義

      本節描述ARMv8內存模型中有關順序和觀察的概念。包含以下子章節:

      .位置

      .順序和可觀察性

      .順序約束

      .完成順序和端點順序

      .內存屏障

      .限定順序域

      有關內存訪問端點順序的更多信息,參考Reordering on page B2-129。

      在ARMv8內存模型中,共享內存屬性指硬件必須在一系列觀察者之間保證內存一致性。參考Memory types and attributes on page B2-122.

      ARMv8架構定義了另外的內存屬性和相關的行為,這些定義在手冊中的系統級內存模型和虛擬內存系統架構章節中。

      Chapter D4 The AArch64 System Level Memory Model

      Chapter D5 The AArch64 Virtual Memory System Architecture.

      參考

      Mismatched memory attributes on page B2-132.

      這里貼一張CPU系統的框圖,這不是最新的CPU描述,僅做參考:

      (圖片來源于網絡)

      1、基本定義:Locations, Memory effects, and Observers

      ARMv8內存模型提供了一系列定義,用來約束內存訪問的順序。ARMv8內存模型定義:

      . 觀察序,不同觀察者所看到的內存訪問順序

      . 抵達序,內存訪問抵達一個端點的順序

      . 機制,控制觀察序和抵達序的機制

      Locations, Memory effects, and Observers

      2、位置(Location):

      ARMv8內存模型對內存中的位置(Location)作如下定義:

      一個位置指內存中的一個字節。

      作為指令執行的一部分,指令可能對內存產生影響。系統中的觀察者可以在內存位置上,看到那條指令產生的影響。ARMv8內存模型提供了如下關于內存影響和觀察者的定義:

      3、內存影響(Memory effect):讀/寫/屏蔽

      一條指令產生的內存影響是指這條指令生成的讀取影響,寫入影響,或者屏障影響。針對內存訪問指令:

      . 當一個內存位置被指令讀取時,將產生一個讀取影響。

      . 當一個內存位置被指令寫入時,將產生一個寫入影響。

      有時,一條指令既能產生內存讀取影響,也能產生內存寫入影響。

      *抒己見:比如原子加,或者比較交換CAS指令,會對內存產生讀取和寫入的雙重影響。

      當且僅當指令I1按指令序出現在指令I2之前,指令I1對內存產生的影響才按指令序,出現在指令I2對內存產生的影響之前。

      ARMv8內存模型描述的目標,即所有的讀取影響和寫入影響,都是指普通共享域(Common Shareability Domain)。如果本節描述的讀取,寫入和內存屏障沒有限定,那么都是指此對應的內存影響。

      *抒己見:文中沒有把“memory effect”翻譯成內存效果或者其它詞語,也許有比內存影響更好的詞語。可能有些程序員(同事)認為對內存讀不會對內存有任何影響,但是對CPU內部的cache影響還是有的,需要考慮cache一致性,讀取內存數據時,也許有其它core在cache中保留了內存臟數據。

      5、觀察者(Observer):PE(Processing element)、代理

      一個觀察者即可以是一個處理核PE(Processing element),也可以是其它產生內存讀寫訪問的代理。

      6、普通共享域(Comman Shareability Domain)

      程序的普通共享域,就是程序產生的內存訪問影響能被域內所有觀察者看的最小共享域。

      五、ARM64創新:排序及其可觀察性

      1、依賴約束、排序約束、APP序:OS和芯片協調邊界

      ARMv8內存模型允許重新排序內存訪問,即亂序執行。本節定義內存訪問重排序有哪些限制:

      . 依賴約束,這是執行單元上確立指令間順序的重要約束。

      . 排序約束,這是在一個內存位置上確立訪問順序的重要約束。

      *抒己見:ARMv8內存模型將遵守依賴約束和排序約束,在這些約束的限制下,體系結構會保證這些指令的順序不會在執行階段重排。

      有一種情況,對共享全局變量有邏輯依賴的程序,其編譯后的關鍵指令對CPU來講,并不存在CPU規定的指令依賴關系,這種邏輯依賴關系是程序員知曉的,CPU和編譯器無法理解。要這些邏輯相關指令在ARM64上按指令序執行,就需要手工在應用程序中增加相應的內存屏障指令,所以,“自己的-自己吃”,程序員需要重視單核中亂序執行對多核間全局變量訪問的影響,多數情況抽象為,生產端的生產過程和完成標記的設置,消費端的完成標記的讀取和消費過程。生成端的生成過程和完成標記的設置是可能亂序的,這是應用程序規定的角色,CPU是不知道這個邏輯關系的,消費端的邏輯也是CPU不知道的。所以應用程序和OS希望CPU理解類似這些邏輯也是困難的。CPU的亂序執行本質上是指令流的動態調度,在維護數據依賴和控制依賴的情況下盡可能快的執行每條指令。

      “Program order”直譯為程序順序,本文按照指令序翻譯。

      2、依賴:劃分界限,寄存器R,數值V和指令I

      ARMv8內存模型定義了以下指令間的依賴:

      *抒己見:ARMv8手冊將“依賴”區分的非常細,我理解其目的就是劃清界限,“我的地盤我做主”,CPU僅僅實現了這些相關的保序特性,依賴以外的亂序都是“未定義”的。以下描述中將出現幾個字母,比如R1,V1,V2,V3,W2,I2等,這些都是寄存器R,數值V和指令I的代稱。

      本文對各種依賴的描述和手冊中的實際順序不一致。我們經常遇到的數據依賴,不管是寄存器訪問指令還是內存訪問指令,有三種類型,RAW(寫后讀),WAR(讀后寫)和WAW(寫后寫),其中RAW是真依賴,其它是假依賴,RAR沒有依賴。

      寄存器依賴

      一個執行單元PE里,第一個數據V1與第二個數據V2存在寄存器依賴,當且僅當:

      . 保存V1數據的寄存器用來計算V2數據 。

      . 數據V1與數據V3有寄存器依賴,數據V3與數據V2也有一個寄存器依賴。

      舉例1:

      ldr x1, [x29, #144]

      add x2, x1, #0xc8

      str x2, [x29, #168]

      舉例2:

      ldr x1, [x29, #144]

      ldr x3, [x29, #168]

      add x3, x3, x1

      str x3, [x29, #168]

      add x2,x3, #0x10

      str x2, [x29, #170]

      *抒己見:保存V1數據的寄存器不包括零值寄存器XZR或者WZR。寄存器依賴主要描述前一個值是計算后一個值的基礎,這是一種基礎的依賴關系,并沒有限定后值的用途。是值與值之間的依賴,通過寄存器搭橋而已。寄存器依賴有兩種情況,一種是直接依賴,另外一種是間接依賴。寄存器依賴,必須從匯編語言層級來識別。描述寄存器依賴關系時沒有提及指令,只提到了數據。

      數據依賴

      讀操作R1與后續寫操作W2存在數據依賴,當且僅當,讀操作R1返回的數據與后續寫操作W2寫入的數據有一個寄存器依賴。

      舉例如下:

      ldr x1, [x29, #144]???? /*從堆棧中讀取數據到寄存器x1中*/

      add x2, x1, #0xc8?????? /*x1寄存器加0xc8后賦值給x2寄存器*/

      str x2, [x29, #168]???? /*把x2寄存器的值存放到堆棧中*/

      *抒己見:這個例子和寄存器依賴的例子沒有差別。 讀后寫被定義為數據依賴,即后面要寫入內存的數據與前面從內存讀出的數據相關。感覺數據依賴和寄存器依賴在相互解釋。數據依賴和寄存器依賴的區別在于,寄存器依賴是后值依賴前值,而沒有定義后值的用途,如果后值作為數據寫回內存就是數據依賴,如果后值作為分支判斷條件,就是控制器依賴,如果后值作為地址使用,就是地址依賴。而數據依賴只是寄存器依賴的一種形式而已。

      有時,編譯器會做指令優化,數據不存回堆棧或者內存中,暫時存放在寄存器中,所以數據依賴和實例展示的情況不一樣。

      控制依賴

      讀操作R1與后續指令I2存在控制依賴,當且僅當以下條件成立:

      .當讀操作R1讀取的數據,與條件分支的判斷值有一個寄存器依賴,同時,I2指令被包含在一個條件分支里。

      .當讀操作R1讀取的數據,與決定指令I3上的同步異常的數據值有一個寄存器依賴,同時,指令I2按指令序排在指令I3后面。

      *抒己見:第一個條件好理解,即R1讀取的數據直接控制了I2指令的執行,但是需要注意條件分支的理解,如果是通過子函數調用,即“bl”分支過來執行I2指令,這個情況應該不是控制依賴,因為這是一個必然走到的分支。

      第二個條件有些隱晦,引入了同步異常,描述為被動的控制依賴,我理解R1的值可能觸發I3指令異常,也可能不觸發I3指令異常,I3后面的I2指令被包含在一個隱藏的條件分支中。這個控制依賴不好理解,實際應用中還沒有遇到過。

      寄存器數據依賴

      一個執行單元PE里,第一個數據V1與第二個數據V2存在寄存器數據依賴,當且僅當如下條件成立:

      . 保存V1數據的寄存器用來計算V2數據,但是V1和V2之間的計算不包含以下情況:

      _ 條件分支的條件由V1來決定

      _ 條件選擇,搬移或者比較的條件由V1決定

      . 數據V1與數據V3有寄存器數據依賴,數據V3與數據V2也有寄存器數據依賴關系。

      *抒己見:保存V1數據的寄存器不包括零值寄存器XZR或者WZR。前面有寄存器依賴,再定義一個寄存器數據依賴的用意是什么?我理解寄存器數據依賴排除了寄存器依賴作為控制依賴的情況,這為投機讀開了綠燈,因為投機讀是可以不受控制依賴限制的。

      地址依賴

      讀操作R1與后續的讀操作R2存在地址依賴,當且僅當R1讀操作返回的數據與R2使用的地址有寄存器數據依賴關系。

      讀操作R1到后續的寫操作W2存在地址依賴,當且僅當R1讀操作返回的數據與W2使用的地址有寄存器依賴關系。

      *抒己見: 如果后續動作是讀,地址依賴僅僅包括寄存器數據依賴,允許地址受控制依賴,即允許投機讀發生。如果后續動作是寫,地址依賴需要包括寄存器依賴中的控制依賴,即不能發生投機寫,因為當分支確定后,如果預測錯誤,寫操作的影響是不能撤銷的。

      3、基于位置的順序和可觀察性

      一個內存位置上的內存影響有下列關系描述:

      Reads-from

      “讀出”關系,把寫入的數據讀取出來。針對同一個內存位置,一個讀取操作配對一個寫入操作,W1寫入的數據被R2讀出來。

      ------Note------

      Reads-from關系表達了讀取由寫入來滿足,然后返回寫入的數據

      ————————

      *抒己見:由于CPU內部的架構實現差異,數據可能并沒有寫入到內存中,而是在內部的cache中,或者本core要讀的數據在另外一個core的cache中。但是reads-from關系仍然按照對實際CPU外部內存的影響來理解。

      Coherence order

      “一致性順序”關系,針對程序中的每個內存位置,規定了所有一致性觀察者的所有寫入的總順序,開始于一個初始值的抽象寫操作。

      ------Note------

      一個內存位置的Coherence order關系,表示寫入這個位置時到達內存時的順序

      ————————

      *抒己見:這里描述的一致性順序,只和寫操作相關,聯想到CPU內部的cache,在MESI協議規定下,有時一個觀察者把數據寫臟后,并不立刻寫到內存,只更新本core的cache,在其它觀察者需要再次寫本位置時,才會發生數據同步。所以,這里隱含的描述了MESI協議的一部分定義。

      Coherence-after

      針對同一個內存位置,寫入W2和另外一個寫入W1,是Coherence-after關系,當且僅當,W2在W1后面,是Coherence order關系。

      針對同一個內存位置,寫入W2和另外一個讀取R1,是Coherence-after關系,當且僅當,R1 Reads-from讀出W3的值,W2與W3是Coherence-after關系。

      *抒己見:這里描述的一致性順序,無法翻譯成中文,保留英文描述“Coherence-after”。一前一后的一致性寫操作定義為“Coherence-after”,一前一后的一致性寫,讀出后一個寫的值是“Coherence-after”。雖然比較難懂,重點就是每一步操作都是一致性可觀察的。

      Overlapping accesses

      “重疊訪問”關系。兩個內存影響重疊,當且僅當它們訪問相同的位置時。兩條指令重疊,當且僅當它們生成的一個或多個內存影響重疊時。

      *抒己見:有時編譯器就會優化多余的重復訪問,添加volatile定義時才會避免優化,處理器對重疊訪問的處理細節被隱藏了,除非芯片設計人員告訴細節。多個PE的重疊訪問和一個PE的重疊訪問,在處理器中實現會不一致。比如MESI協議中,一個PE讀到本cache的臟數據是沒有狀態變化和內存影響的。

      Observed-by

      一個觀察者的讀取或者寫入RW1被另外一個觀察者的寫入W2觀察到,當且僅當W2與RW2是“coherence-after”關系。

      一個觀察者的寫入W1被另外一個觀察者的讀取R2觀察到,當且僅當R2與W1是“Reads-from”讀出關系。

      DMB FULL

      DMB FULL是包含LD或ST的DMB全集。

      如果本節涉及的DMB沒有任何限定,那么它指的是所有類型的DMB。除非定義了特定的可共享域,否則DMB適用于通用共享域。

      適用于DMB的所有屬性也適用于相應的DSB指令

      4、排序關系

      除了單個內存位置的排序關系之外,ARMv8內存模型還提供了發生在多個內存位置的內存影響的排序關系。這些關系描述如下:

      Dependency-ordered-before

      一個觀察者生成的一個內存讀取影響,和這個觀察者生成另外一個內存影響之間的外部可見的順序,是由依賴關系創建的。

      一個內存讀取R1依賴排序靠前Dependency-ordered-before來自同一觀察者的內存讀寫RW2,當且僅當?R1在指令序上排在RW2之前,而且滿足下列任一條件:

      . R1與RW2有地址依賴或者數據依賴關系

      . RW2是一個寫入W2,在R1與W2之間有控制依賴

      . RW2是一個讀取R2,指令序上排在指令I3后面,I3將產生上下文同步事件,在R1與I3之間有控制依賴。

      . RW2是一個寫入W2,指令序上排在一個讀或者寫RW3后面,R1與RW3之間有地址依賴。

      . RW2是一個寫入W2,與寫入W3是Coherence-after關系,R1與W3之間有控制依賴或者數據依賴。

      . RW2是一個讀取R2,與寫入W3是讀出關系,在R1與W3之間有一個控制依賴或者數據依賴。

      *抒己見:這里描述了以依賴為中心的多個內存位置訪問的指令執行排序關系,終于把前面描述的關系用上了。有這些依賴關系時,讀R1需要排在前面執行,其它情況是不受約束的。所以,沒有上述指定的依賴關系時,不同位置的讀寫操作會被亂序執行。

      Atomic-ordered-before

      即使沒有依賴關系,互斥讀Load-Exclusive和互斥寫Store-Exclusive也有保序能力。

      一個內存讀寫RW1原子排序靠前Atomic-ordered-before來自同一觀察者的內存讀寫RW2,當且僅當指令序上,RW1排在RW2前面,并且滿足以下任一情況:

      . RW1是讀取R1,RW2是寫入W2,當R1和W2都由原子指令生成的,或者正好是訪問同一位置的互斥讀/互斥寫指令對。

      . RW1是原子指令生成的寫入W1,或者一個成功的互斥寫指令生成的寫入W1。RW2是一個Acquire語義或者AcquirePC語義生成的讀取R2,并且R2?Reads-from讀出W1。

      *抒己見:原子指令和互斥指令是自帶排序屬性的,有沒有依賴關系不重要,這個也是ARM64架構的指令集特點。

      Barrier-ordered-before

      屏障指令排序優先,相比同一觀察者在屏障指令后的其它內存影響,屏障指令的內存影響會早生效。一個讀取或者寫入RW1和另外一個讀取或者寫入RW2的關系是屏障排序靠前關系,當且僅當RW1在指令序上排在RW2前,而且滿足以下任何一種情況:

      .RW1在指令序上排在一個DMB FULL指令之前,或者包含Acquire語義和Release語義的原子指令之前,屏障指令和原子指令按指令序也排在RW2前面。

      .RW1是由Release語義的指令生成的寫入W1,而RW2是有Acquire語義的指令生成的讀取R2。

      .RW1是讀取R1,并且:

      -????R1在指令序上排在DMB LD前,指令序上也在RW2前。

      -????R1由Acquire語義或者AcquirePC語義的指令生成。

      .RW2是寫入W2,并且:

      -????RW1是寫入W1,指令序上排在DMB ST前,指令序上也排在W2前。

      -????W2由Release語義的指令生成

      -????RW1在指令序上排在一個具有Release語義的指令生成的W3前,W2與W3是Coherence-after關系。

      *抒己見:內存墻阻止了后續指令翻墻提前執行,不管是讀取和寫入指令,在CPU微架構上可能是通過阻止流水線第一階段的后續指令分發來實現。同時,包括Acquire語義和Release語義的原子指令自帶內存墻屬性,將讀寫指令與墻指令合并為一條指令。

      需參考互斥和原子指令的詳細介紹,本文暫時不展開。

      Ordered-before

      如果說任意一對內存影響是順序的,只有它鏈成的順序訪問從外部觀察也是一致的。

      一個讀取或者寫入RW1 Ordered-before排序靠前另外一個讀取或者寫入RW2,當且僅當以下任何一種情況適用時:

      RW1 is Observed-by RW2.

      RW1 is Dependency-ordered-before RW2.

      RW1 is Atomic-ordered-before RW2.

      RW1 is Barrier-ordered-before RW2.

      RW1 is Ordered-before?一個讀或者寫,而這個讀或者寫又is Ordered-before RW2

      六、ARM64可控規則:系統中觀察者之間的交互

      1、使用共享變量來通信

      系統中觀察者之間的交互不局限于一致性內存中使用共享變量來通信。比如,一個觀察者可以配置中斷控制器觸發一個中斷到另外一個觀察者,作為一種消息通信方式。這些交互典型的特點是涉及一個額外的代理,它定義了兩個不同觀察者間建立通信鏈路的指令順序。當交互形式結合到共享變量的使用時,就必須使用DSB指令來確保它們之間的順序。

      2、所有內存完成規則的定義

      對所有的內存,完成規則的定義如下:

      .一個共享域內,對一個位置的讀取R1是完成的,滿足以下所有條件:

      -????共享域內,觀察者對相同位置的任何寫入W1與讀取R1是Coherence-after關系

      -????共享域內,任何R1相關的地址轉換表都walk完成。

      .一個共享域內,對一個位置的寫入W1被認為是完成的,需滿足以下所有條件:

      -????共享域內,一個觀察者對相同位置的任何寫與W1是Coherence-after關系。

      -????共享域內,一個觀察者對相同位置的任何讀與W1是Reads-from關系,或者與W1是Coherence-after關系的另外一個寫是Reads-from關系。

      -????共享域內,與寫相關的所有地址轉換表都walk完成。

      .共享域內地址轉換表完成,包括轉換表條目的刷新,共享域內相關的轉換表walk完成,TLB刷新。

      .cache維護指令完成,在共享域內,當指令的訪存效果在共享域內完成,這條指令觸發的地址轉換表同步在共享域內完成。

      .TLB無效指令完成,當所有內存訪問使用的TLB條目都無效完成。

      任何cache和TLB維護指令的完成,包括它在所有受指令和DSB操作影響的PE上完成。而DSB是保證維護指令被外部可視所必需的。

      此外,對于Device-nGnRnE內存,一個內存映射外設上的位置,讀取和寫入將出現副作用,當讀取和寫入:

      .可以開始影響內存映射外設的狀態

      .可以觸發所有相關的副作用,無論他們是否影響到其它的外圍設備,PEs,或者內存。

      *抒己見:cache、TLB、MMU等等都太專業了,主要get的點是內存影響涉及到cpu內部這些模塊,包括緩存和地址管理,不僅僅是內存那個位置的值發生了改變。

      Device內存的副作用,主要表現在寫一個控制地址A,device的另外一個狀態地址B的值會有變化。這是外設的一個顯著特征。不像內存,寫A地址時,B地址的內容不會變化。

      3、外設

      本節定義內存映射外設和讀取和寫入外設的總順序,外設一致性順序定義如下:

      一個內存映射外設占用一段內存區域(大小和實現相關),通過load和store指令訪問。對內存映射外設的內存訪問可能產生副作用,比如一個寫入將導致外設執行一個額外的動作。從內存映射外設的地址中讀取的值可能與最后一個寫入此地址的數據值并不一致。因此,內存映射外設的訪存效果可能不會出現Reads-from和Coherence order的關系。

      *抒己見:驅動人員對此應該深有體會,對于寫清除的寄存器,再回讀就不再是寫入的值了。對一個控制和狀態集合的寄存器,寫和讀操作可能訪問的完全是兩個寄存器。所以,內存的一致性關系在這里不適用。

      鯤鵬開發重點-–扭轉x86乾坤的挑戰,ARM64內存模型

      內存映射外設的Peripheral coherence order是對該外設的所有讀寫操作的總順序。

      對于一個讀取或者寫入RW1,與針對此外設的另外一個讀取或者寫入RW2,當出現下列情況,RW1在RW2之前呈現Peripheral coherence order:

      .RW1和RW2使用Non-cacheable或者Device屬性,RW1和RW2是Ordered-before關系

      .RW1和RW2使用?Device-nGnRE或者Device-nGnRnE屬性,RW1按指令序排在RW2之前。

      *抒己見:Device地址屬性包括GRE控制,Gathering or non Gathering (G or nG):多個訪問合并為一個總線訪問,Re-ordering (R or nR):訪問同一設備是否可亂序?,Early Write Acknowledgement (E or nE):外設訪問時,是允許互聯邏輯的buffer提前返回ACK,而不等待真正的外設訪問完成信號。

      一個讀取或者寫入RW1與另外一個讀取或者寫入RW2是Out-of-band-ordered-before關系,當且僅當以下任一種情況:

      .RW1在指令序上排在DSB指令前,而DSB指令開始于一個實現定義的指令序,它間接導致RW2的生成。

      .RW1與一個讀取或者寫入RW3是Ordered-before關系,而RW3與RW2是Out-of-band-ordered-before關系。

      如果一個訪存效果M1與另外一個讀或者寫M2是Out-of-band-ordered-before,那么所有觀察者都將看到M1在M2之前發生。

      *抒己見:雞生蛋,蛋生雞。搞懂亂序原理解決亂序問題,解決亂序問題搞懂亂序原理。

      七、附-參考資源:ARM?? Architecture Reference Manual

      ARM?? Architecture Reference Manual

      ARMv8, for ARMv8-A architecture profile

      DDI0487D_b_armv8 (ID042519)

      B2.3? Definition of the ARMv8 memory model

      側記:像鯤鵬,去展翅高飛,共贏計算新時代

      有一個朋友說,他的技術博客有一年多沒有更新。他覺得自己主要是太懶,因為他的工作很安逸、沒有996的壓力,但也沒有新技術的激勵,過于平淡的工作,也讓他忘了自己的初衷。

      很多朋友認為,還是要有目標才有動力,對于我們普通人來說,生活中需要有個trigger讓自己努力起來。

      也許是生活壓力,也許是某人給的刺激,也許是自己的興趣愛好,也許就是為了愛的人、愛的家、愛的國!!

      他說,好吧,最近看華為被美國制裁刷了屏,內心很不平靜,罵人沒用,不罵又憋內傷,我輩俗人只有相信自強不息以立志!

      向朋友們致敬!

      ARM 鯤鵬

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:【安全算法之概述】一文帶你簡要了解常見常用的安全算法
      下一篇:輕松掌握Oracle索引(二)
      相關文章
      亚洲国产精品免费视频| 久久久久亚洲Av片无码v| 国产成人高清亚洲| 亚洲日韩在线中文字幕综合| 亚洲伊人久久大香线蕉AV| 亚洲精品国产国语| 久久精品国产亚洲AV蜜臀色欲| 亚洲成AV人综合在线观看| 亚洲精品韩国美女在线| 亚洲精品免费视频| 亚洲最大福利视频网站| 亚洲狠狠久久综合一区77777| 亚洲a一级免费视频| 亚洲国产成人久久综合碰碰动漫3d| 亚洲av无码不卡一区二区三区| 亚洲av永久无码精品表情包| 亚洲AV日韩精品久久久久久久| 亚洲国产第一站精品蜜芽| 人人狠狠综合久久亚洲婷婷| 久久亚洲精品国产精品黑人| 亚洲伊人tv综合网色| 亚洲精品高清久久| 亚洲乱人伦精品图片| 中文字幕无码亚洲欧洲日韩| 亚洲国产精品无码第一区二区三区| 亚洲第一街区偷拍街拍| 国产成人精品亚洲一区| 亚洲午夜福利精品无码| 国产亚洲人成A在线V网站| 国产亚洲婷婷香蕉久久精品 | 亚洲av无码一区二区三区不卡| 久久伊人久久亚洲综合| 亚洲视频一区在线观看| 亚洲日本香蕉视频观看视频| 国产婷婷综合丁香亚洲欧洲| 亚洲JIZZJIZZ妇女| JLZZJLZZ亚洲乱熟无码| 久久久久亚洲精品成人网小说| 亚洲精品中文字幕乱码影院| 456亚洲人成在线播放网站| 蜜桃传媒一区二区亚洲AV |