Go中runtime.GOMAXPROCS的設置致使的性能問題

        首先咱們應該明確,並行和併發的區別,我以前文章中有詳細的解釋。概要說就是,併發通常都是被內核經過時間片或者中斷來控制的,一旦遇到IO阻塞或者時間片用完,就會轉移線程的使用權。單核不可能有並行,同一時間只能有一個任務在調度。ubuntu

        Go中runtime.GOMAXPROCS能夠設置多核執行任務。並行比較適合cpu計算密集型。若是IO密集型使用多核反而會增長cpu切換的成本。併發

 

須要特地說明一點是,你在測試併發的時候,每每會把一個函數寫成死循環並作計算,你雖然這段函數用go關鍵詞併發了,可是你會發現他沒法執行後面的邏輯。你須要作的是配置多核,或者是time.Sleep()。  這是爲何 ? Golang是本身管理調整goroutine,若是你的一個func始終不釋放資源,那麼其餘的goroutine不會去搶奪資源。 固然這樣的場景只有在測試時候遇到,正常場景下不可能沒有中斷和堵塞的狀況。 函數

 

那爲什麼說設置的核心越多反而會下降性能?看下面代碼:oop

package main

import(
	"fmt"
	"time"
	"runtime"
)

var quit chan int = make(chan int)

func loop(){
	for i:=0 ;i<10000; i++{
		fmt.Printf("%d\n", i)		
	}
	
	quit <- 0
}

func main(){
	fmt.Println(runtime.NumCPU()) // 默認CPU核心數
	time.Sleep(2*time.Second)
	a := 5000
	t0 := time.Now()      // 起點時間
	//runtime.GOMAXPROCS(1) // 設置執行使用的核心數
	
	for i:=1; i<= a; i++{
		go loop()
	}
	
	for i:=0; i< a; i++{
		<-quit
	}
	
	endTime := time.Since(t0) // 耗時
	fmt.Println("運行時間", endTime)
	
}

        首先說明個人電腦是8核ubuntu ,  其中runtime.GOMAXPROCS(1) 被註釋, 獲得的結果是 2m13s 。    性能

取消註釋,使用一個核心執行此程序,獲得的確實1m 20s。 (都是屢次執行取平均值)。    測試

        此處還要注意點一點就是: Go默認執行使用的CPU核心數爲系統CPU最大核心。ui

        有的碼友可能以爲是channel的問題, 多個協程同時寫入,帶來的併發問題。其實否則,此處瓶頸在於fmt,spa

因爲多個協程同時往stdout寫入, 縱然前面執行再快,最後仍是要單線程輸出到屏幕,致使的性能問題,若是fmt換爲其餘操做,就能夠顯示出GOMAXPROCS的好處。.net

相關文章
相關標籤/搜索