2021-03-05:go中,io密集型的應用,好比有不少文件io,磁盤io,網絡io,調大GOMA

2021-03-05:go中,io密集型的應用,好比有不少文件io,磁盤io,網絡io,調大GOMAXPROCS,會不會對性能有幫助?爲何?
福哥答案2021-03-05:golang

這是面試中被問到的。實力有限,真正的答案還不知道。面試

答案1:
調節這個參數影響的是P的個數,也就影響了M(線程)幹活的個數。至關於你能夠有更多的執行線程。
先以網絡io來講,網絡io 在golang 裏面是異步的,用epoll池作的io複用。每一個網絡調用其實都是異步的,發數據給到內存,調度權就可讓給其餘goroutine了,因此,其實一個線程能處理過來的話,性能是不會差的,這個時候你加多P其實提高不大。只有你單線程處理不過來這些網絡io的時候(每一個都處理很慢),加多P纔有明顯提高
若是是磁盤io的話,這個有點特殊,磁盤io不是異步的,沒有aio這種方式。因此你的磁盤io調用下去就卡住M了,這個時候等sysmon發現系統調用超時纔會搶佔M,這一來回就耗費時間了,因此,這種狀況下你幹活的M多一點確實能帶來一些性能的提高,至關於並行幹活的M多一些。
不管哪一種狀況,P的個數都不建議超過本機cpu的個數。由於多個cpu纔是真正的並行執行,上層都是經過調度切換模擬出來的。網絡

答案2:
GOMAXPROCS 用默認的,就是CPU的硬件線程數目,
對於大部分IO密集的應用是不合適的。
至少應該配置到硬件線程數目的5倍以上, 最大256。
GO的調度器是遲鈍的,它極可能什麼時都沒作,直到M阻塞了想當長時間之後,纔會發現有一個P/M被syscall阻塞了。而後,纔會用空閒的M來強這個P。
補充說明:調度器遲鈍不是M遲鈍,M也就是操做系統線程,是很是的敏感的,只要阻塞就會被操做系統調度(除了極少數自旋的狀況)。可是GO的調度器會等待一個時間間隔纔會行動,這也是爲了減小調度器干預的次數。也就是說,若是一個M調用了什麼API致使了操做系統線程阻塞了,操做系統馬上會把這個線程M調度走,掛起等阻塞解除。這時候,Go調度器不會立刻把這個M持有的P搶走。這就會致使必定的P被浪費了。
這就是爲什麼,GOMAXPROCS 過小,也就是P的數量太少,會致使IO密集(或者syscall較多)的go程序運行緩慢的緣由。
那麼,GOMAXPROCS 很大,超過硬件線程的8倍,會不會有開銷呢?
答案是,開銷是有的,可是遠小於Go運行時遲鈍的調度M來搶奪P而致使CPU利用不足的開銷。異步

【GO語言】合理配置GOMAXPROCS提高一倍以上的性能
GOMAXPROCS你設置對了嗎?
go 協程詳解
2021-03-05:go中,io密集型的應用,好比有不少文件io,磁盤io,網絡i...如何解答呢?ide

相關文章
相關標籤/搜索