簡體   English   中英

Golang:為什么runtime.GOMAXPROCS限制為256?

[英]Golang: why runtime.GOMAXPROCS is limited to 256?

我在MacBook和Ubuntu上使用golang 1.7.3,發現runtime.GOMAXPROCS限制為256。有人知道此限制來自何處嗎? 是否在任何地方都有記錄,為什么會有限制? 這是實現優化嗎?

在此頁面上,我僅能找到256個參考,該參考描述了golang的運行時軟件包: https ://golang.org/pkg/runtime/。 runtime.MemStats結構具有幾個大小為256的狀態數組:

type MemStats struct {
    ...
    PauseNs       [256]uint64 // circular buffer of recent GC pause durations, most recent at [(NumGC+255)%256]
    PauseEnd      [256]uint64 // circular buffer of recent GC pause end times

這是我使用的示例golang代碼:

func main() {
    runtime.GOMAXPROCS(1000)
log.Printf("GOMAXPROCS %d\n", runtime.GOMAXPROCS(-1))

}

打印GOMAXPROCS 256

PS另外,有人可以指出我有關此GOMAXPROCS與golang調度程序使用的OS線程計數的關系的文檔(如果有的話)。 我們是否可以觀察到運行GOMAXPROCS OS線程的經過編譯的代碼?

編輯:感謝@twotwotwo指出GOMAXPROCS如何與OS線程相關。 仍然很有趣的是,文檔沒有提到這個256的限制(除了在MemStats結構中可能或可能不相關的限制)。

我想知道是否有人知道這256個數字的真正原因。

軟件包runtime文檔闡明了GOMAXPROCS與OS線程的關系:

GOMAXPROCS變量限制了可以同時執行用戶級Go代碼的操作系統線程的數量。 對於代表Go代碼的系統調用中可以阻止的線程數量沒有限制; 那些不計入GOMAXPROCS限制。 該軟件包的GOMAXPROCS函數查詢並更改限制。

因此,您可能會看到不止一個GOMAXPROCS OS線程(因為某些線程在系統調用中被阻塞,並且對數量沒有限制),或者更少(因為GOMAXPROCS僅被記錄為限制線程數,而沒有確切地規定它)。

我認為限制GOMAXPROCS符合該文檔的精神-您指定可以運行1000個運行Go代碼的OS線程是可以的,但是運行時決定“僅”運行256個。這不會限制激活的goroutine的數量,因為它們當一個goroutine塊(例如,等待網絡讀取完成)時,Go的內部調度程序將在同一OS線程上啟動其他工作。

Go團隊可能會選擇這種方法,以最大程度地減少Go程序最終運行的OS線程的機會是當今大多數具有內核的機器的幾倍; 這將導致更多的OS上下文切換,這可能比如果將GOMAXPROCS保持在現有CPU內核數量以下而進行的用戶模式goroutine切換要慢。 或者,對於設計Go的內部調度程序來說,在GOMAXPROCS上設置上限可能只是很方便。

Goroutines vs Threads並不完美,例如goroutines現在還沒有分段堆棧,但是它可以幫助您了解引擎蓋下的情況。

請注意,從下一個Go 1.10(Q1 2018)開始, GOMAXPROCS將受到...的限制。

運行時不再人為地限制GOMAXPROCS (以前僅限於1024)。

請參閱Austin Clements( aclements )的 ee55000提交 ,該版本修復了問題15131

既然allp是動態分配的,那么就不需要對GOMAXPROCS設置硬上限了。


allp在這里定義

參見commit e900e27

runtime :清理allp循環

現在, allp長度為gomaxprocs ,這意味着allp[i]都不為nil或不處於_Pdead狀態。
這樣就可以用正常范圍循環替換allp上幾種不同樣式的循環。

for i := 0; i < gomaxprocs; i++ { ... } for i := 0; i < gomaxprocs; i++ { ... }循環可以簡單地遍歷allp
同樣, range loops over allp[:gomaxprocs]可以在allp范圍allp

檢查p == nil || p.state == _Pdead循環 p == nil || p.state == _Pdead不再需要檢查。

如果失效的P不影響p == nil ,則檢查p == nil循環不必進行檢查。 我檢查了所有這些循環,實際上都不受死P的影響。 可能會影響一個循環,這可以通過將p.gcAssistTimeprocresize

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM