Go記憶體架構,一個有趣的問題

TIGERB發表於2022-05-22

在學習Go語言記憶體管理部分過程中,發現了一個很有意思的問題,今天就藉助這篇文章:

  • 1.把這個問題也拋給大家,建議大家看見這個問題後,可以先自己思考一番?之後再讀下文。
  • 2.進一步強化大家對Go記憶體架構的理解

開始本篇文章之前,我們快速回顧下「Go記憶體架構」相關的核心知識點,溫故知新

快速回顧「TCMalloc記憶體管理架構」

先來簡單回顧下「TCMalloc記憶體管理架構」。詳細講解可檢視之前的文章《18張圖解密新時代記憶體分配器TCMalloc》

痛點

多執行緒時代 ---> 執行緒共享記憶體 ---> 執行緒申請記憶體會產生競爭 ---> 競爭加鎖 ---> 加鎖影響效能。

解法

每個執行緒上增加記憶體快取。

簡易架構圖如下:

http://cdn.tigerb.cn/20210120132244.png

快速回顧「Go記憶體管理架構」

接著簡單回顧下「Go記憶體管理架構」。詳細講解可檢視之前的文章《淺析Go記憶體管理架構》

痛點

同上。

解法

同上,基於「TCMalloc」實現。

簡易架構圖如下:

http://cdn.tigerb.cn/20220405224809.png

有趣的問題

關於這個有趣的問題,細心的朋友可能已經發現了,不賣關子了問題如下:

為什麼Go的記憶體管理器的執行緒快取是mcache被邏輯處理器p持有,而並不是被真正的系統執行緒m持有?

個人思考時間

是不是很有意思,關於這個問題。對面的你不妨先停下來思考幾分鐘:

為什麼?

解密

按照原TCMalloc的設計思想,執行緒快取mcache確實應該被繫結到系統執行緒M上。

那麼我們就假設:按照原TCMalloc的思想,把mcache繫結系統執行緒M。接著我們只需要看看這個假設有什麼問題即可。

要論證這個假設需要先來簡單看看「Go的排程模型GMP」。

Go的排程模型GMP

直接上入門級「Go的排程模型GMP」架構圖:

http://cdn.tigerb.cn/20220416214452.png

關於「Go的排程模型GMP」的原理,大家應該看了無數文章,我這裡就不細說了,如果還有不熟悉可以自行搜尋哈。

這裡簡單提下關於GMP的入門級知識哈,其實GMP對應的只是Go語言自身的邏輯結構而已,含義如下:

  • M:代表結構體m,全稱Machine,這個結構體的核心是會和真正的系統執行緒thread繫結。
  • G:代表結構體g,全稱Goroutine,這個結構體就是大家熟知的協程,簡單理解其實就是這個結構體繫結了一個有著被併發執行需求的函式。
  • P:代表結構體p,全稱Processor,這個結構體表示邏輯處理器,通過這個結構體和計算機的邏輯處理器建立對應關係,P的數量通常和計算機的邏輯處理器數量一致通過runtime.GOMAXPROCS(runtime.NumCPU())設定。

三者的簡單職責以及關係:

  • P

    • 和一個M互相繫結
    • 維護了一個可執行G的佇列
  • M

    • 和一個P互相繫結
    • 負責執行G的排程,通過排程當前M繫結的PG佇列、以及全域性G佇列,達到G可被併發執行的目的。
    • 負責執行P排程過來的當前G

此階段結論:以上的排程過程P的數量和M的數量是一一對應的,所以把mcache繫結系統執行緒M上和P看起來都可以。所以我們上面的假設「按照原TCMalloc的思想,把mcache繫結系統執行緒M」目前看起來確實也沒啥問題。

我們繼續往下看,一種特殊的場景M會和P解綁。

I/O操作的系統呼叫

G執行一個I/O操作的系統呼叫時,比如readwrite,因為系統呼叫過程中的阻塞(原因:核心往使用者態拷貝資料的過程產生的阻塞,不在本文範疇,後續文章詳解)問題,會發生如下操作:

  • 當前G(我們命名為g1)的M(我們命名為m1)和當前的P(我們命名為p1)解綁
  • 上面的p1會繫結一個其他的M(m2)
  • m1執行完成系統呼叫之後會被放到閒置M連結串列裡

http://cdn.tigerb.cn/20220416223807.png

由於m1會被放進閒置連結串列,這是不是就意味著m1上的mcache當前就不能被複用,所以這樣看起來是不是mcache繫結到p1上更合適。

結論: 由於M可能因為執行一個I/O操作的系統呼叫被阻塞(原因:核心往使用者態拷貝資料的過程產生的阻塞),M會和當前P解綁,當前P繫結其他閒置或者新的M,之前的M結束系統呼叫會被放進閒置M連結串列。之前的Mmcache就不會得到有效的複用,反而mcache繫結到P上就不存在這個問題,所以mcache繫結到P上更合適。

檢視《Go語言輕鬆進階》系列更多內容

連結 http://tigerb.cn/go/#/kernal/

相關文章