2013-11-03 81 views
9

我正在閱讀關於go包「runtime」,看到我可以在其他(func GOMAXPROCS(n int))中設置可用於運行我的程序的CPU單元數。我可以強制一個goroutine在我選擇的特定CPU上運行嗎?是否可以強制在特定的CPU上運行例程?

+0

FWIW去1.5據說有一個「智能調度」該CPU的更準確,避免高速緩存未命中走程序之間去。我想這就像CPU親和力... – rogerdpack

回答

10

在現代Go中,我不會將goroutines鎖定到線程以提高效率。去1.5 added goroutine scheduling affinity, to minimize how often goroutines switch between OS threads。並且必須權衡CPU之間剩餘遷移的成本,以避免用戶模式調度器的好處,從而避免上下文切換到內核模式。最後,當轉換成本是一個真正的問題時,有時更好的焦點是改變你的程序邏輯,所以它需要更少的開關,比如通過交流批量工作而不是單個工作項目。

但即使考慮到所有這些,有時你只需要鎖定一個goroutine,就像C API需要它時一樣,我會假設情況如下。


如果整個程序與GOMAXPROCS=1,然後it's relatively simple to set a CPU affinity by calling out to the taskset utility from the schedutils package運行。

我以爲你運氣不好,如果GOMAXPROCS > 1因爲那麼goroutines are migrated between OS threads at runtime。實際上,James Henstridge指出你可以使用runtime.LockOSThread()來防止你的goroutine遷移。儘管如此,我不知道任何Go stdlib函數會在您將goroutine鎖定之後設置當前線程的CPU關聯。您可能可以使用cgo並撥打pthread_setaffinity_np,因爲顯然是Go uses pthreads in cgo mode。由於我們正在討論系統調用,因此操作系統的細節會有所不同。

(如果你的整個程序是純粹的圍棋(無C連接的),它可能工作調用sched_setaffinity經由syscall模塊零pid參數。但是,這將是非常棘手。)

+5

雖然你可以用'runtime.LockOSThread'將一個goroutine鎖定到一個特定的OS線程。這可以與底層操作系統CPU親和程序一起使用來實現目標。 –

+0

哦,謝謝!更新。 – twotwotwo

1

取決於你的工作量,但有時每個CPU啓動一個go進程是有益的,將gomaxprocs設置爲1,並使用taskset將進程固定到CPU。下面是對這樣一個話題摘自真棒fasthttp庫:

  • 使用reuseport 聽衆。
  • 使用GOMAXPROCS = 1爲每個CPU內核運行單獨的服務器實例。
  • 使用taskset將每個服務器實例固定到單獨的CPU內核。
  • 確保多隊列網卡的中斷在CPU內核之間均勻分佈。有關 的詳細信息,請參閱this article
  • 使用Go 1.6,因爲它提供了一些相當大的性能改進。

來源:https://github.com/valyala/fasthttp#performance-optimization-tips-for-multi-core-systems

相關問題