How does GoLang know how many CPUs to use?

  sonic0002        2020-12-29 23:22:15       7,454        0          English  简体中文  繁体中文  ภาษาไทย  Tiếng Việt 

當在 Linux 系統上執行lscpu指令時,它會列出機器上的 CPU 資訊。舉個例子,如果有一個 CPU 具有 2 個核心,且每個核心有兩個執行緒,則表示共有 4 個核心可用。

現在讓我們看看 GoLang 程式會識別多少個核心。

從輸出結果來看,NumCPUGOMAXPROCS 都輸出 4,這是預期的結果。Go 執行時期是如何取得這個資訊的?它是透過類似 lscpu 或 /proc/cpuinfo 的指令取得嗎?讓我們深入研究 GoLang 的原始碼。

runtime/debug.go中,它說明這個值來自全域變數ncpu,這個變數在程序啟動時設定,一旦設定後就不會改變。

ncpu是在哪裡設定的?在 runtime 目錄中使用 grep 搜尋這個關鍵字,在runtime/os_linux.go中,有一個函數osinit(),它呼叫getproccount()來取得ncpu的值。

getproccount()函數內部,它呼叫sche_getaffinity(),這個函數會有一個輸出buf,其中每個值為 1 的位元都會被視為一個核心。

這個函數sche_getaffinity()是一個使用 Go 組合語言定義的原生函數。其實作可以在runtime/sys_linux_amd64.s中找到。

從上面可以看出,ncpu的值與lscpu的輸出結果並不相同,它是作業系統分配給目前程序的 CPU 數量。在多數情況下,ncpu的值與作業系統上可用的 CPU 數量相同,這是因為作業系統預設會允許一個程序使用所有可用的 CPU。如果想要限制一個程序使用的 CPU 數量,可以使用來自cgroupcpuset來進行更改。

例如,讓我們建立一個名為gocpu的 cgroup。

cgcreate -g cpuset:/gocpu

如果想要只允許 cgroup gocpu 使用 CPU 0-1,可以執行

#echo '0' > cpuset.mems
#echo '0-1' > cpuset.cpus
#echo $$ > tasks

然後讓 bash shell 在這個新的 cgroup 中執行,並再次啟動 Go 程式,它現在就只有 2 個核心可以使用了。

參考:https://www.toutiao.com/i6872354717305930254/

CPU  GOLANG  NCPU 

       

  RELATED


  0 COMMENT


No comment for this article.



  RANDOM FUN

Crazy wires