新聞中心
Go語言具有支持高并發(fā)的特性,可以很方便地實現(xiàn)多線程運算,充分利用多核心 cpu 的性能。

成都創(chuàng)新互聯(lián)專注于圖木舒克企業(yè)網(wǎng)站建設(shè),響應式網(wǎng)站,商城網(wǎng)站開發(fā)。圖木舒克網(wǎng)站建設(shè)公司,為圖木舒克等地區(qū)提供建站服務。全流程按需搭建網(wǎng)站,專業(yè)設(shè)計,全程項目跟蹤,成都創(chuàng)新互聯(lián)專業(yè)和態(tài)度為您提供的服務
眾所周知服務器的處理器大都是單核頻率較低而核心數(shù)較多,對于支持高并發(fā)的程序語言,可以充分利用服務器的多核優(yōu)勢,從而降低單核壓力,減少性能浪費。
Go語言實現(xiàn)多核多線程并發(fā)運行是非常方便的,下面舉個例子:
package main
import (
"fmt"
)
func main() {
for i := 0; i < 5; i++ {
go AsyncFunc(i)
}
}
func AsyncFunc(index int) {
sum := 0
for i := 0; i < 10000; i++ {
sum += 1
}
fmt.Printf("線程%d, sum為:%d\n", index, sum)
}運行結(jié)果如下:
線程0, sum為:10000
線程2, sum為:10000
線程3, sum為:10000
線程1, sum為:10000
線程4, sum為:10000
在執(zhí)行一些昂貴的計算任務時,我們希望能夠盡量利用現(xiàn)代服務器普遍具備的多核特性來盡量將任務并行化,從而達到降低總計算時間的目的。此時我們需要了解 CPU 核心的數(shù)量,并針對性地分解計算任務到多個 goroutine 中去并行運行。
下面我們來模擬一個完全可以并行的計算任務:計算 N 個整型數(shù)的總和。我們可以將所有整型數(shù)分成 M 份,M 即 CPU 的個數(shù)。讓每個 CPU 開始計算分給它的那份計算任務,最后將每個 CPU 的計算結(jié)果再做一次累加,這樣就可以得到所有 N 個整型數(shù)的總和:
type Vector []float64
// 分配給每個CPU的計算任務
func (v Vector) DoSome(i, n int, u Vector, c chan int) {
for ; i < n; i++ {
v[i] += u.Op(v[i])
}
c <- 1 // 發(fā)信號告訴任務管理者我已經(jīng)計算完成了
}
const NCPU = 16 // 假設(shè)總共有16核
func (v Vector) DoAll(u Vector) {
c := make(chan int, NCPU) // 用于接收每個CPU的任務完成信號
for i := 0; i < NCPU; i++ {
go v.DoSome(i*len(v)/NCPU, (i+1)*len(v)/NCPU, u, c)
}
// 等待所有CPU的任務完成
for i := 0; i < NCPU; i++ {
<-c // 獲取到一個數(shù)據(jù),表示一個CPU計算完成了
}
// 到這里表示所有計算已經(jīng)結(jié)束
}這兩個函數(shù)看起來設(shè)計非常合理,其中 DoAll() 會根據(jù) CPU 核心的數(shù)目對任務進行分割,然后開辟多個 goroutine 來并行執(zhí)行這些計算任務。
是否可以將總的計算時間降到接近原來的 1/N 呢?答案是不一定。如果掐秒表,會發(fā)現(xiàn)總的執(zhí)行時間沒有明顯縮短。再去觀察 CPU 運行狀態(tài),你會發(fā)現(xiàn)盡管我們有 16 個 CPU 核心,但在計算過程中其實只有一個 CPU 核心處于繁忙狀態(tài),這是會讓很多Go語言初學者迷惑的問題。
官方給出的答案是,這是當前版本的 Go 編譯器還不能很智能地去發(fā)現(xiàn)和利用多核的優(yōu)勢。雖然我們確實創(chuàng)建了多個 goroutine,并且從運行狀態(tài)看這些 goroutine 也都在并行運行,但實際上所有這些 goroutine 都運行在同一個 CPU 核心上,在一個 goroutine 得到時間片執(zhí)行的時候,其他 goroutine 都會處于等待狀態(tài)。從這一點可以看出,雖然 goroutine 簡化了我們寫并行代碼的過程,但實際上整體運行效率并不真正高于單線程程序。
雖然Go語言還不能很好的利用多核心的優(yōu)勢,我們可以先通過設(shè)置環(huán)境變量 GOMAXPROCS 的值來控制使用多少個 CPU 核心。具體操作方法是通過直接設(shè)置環(huán)境變量 GOMAXPROCS 的值,或者在代碼中啟動 goroutine 之前先調(diào)用以下這個語句以設(shè)置使用 16 個 CPU 核心:
runtime.GOMAXPROCS(16)
到底應該設(shè)置多少個 CPU 核心呢,其實 runtime 包中還提供了另外一個 NumCPU() 函數(shù)來獲取核心數(shù),示例代碼如下:
package main
import (
"fmt"
"runtime"
)
func main() {
cpuNum := runtime.NumCPU() //獲得當前設(shè)備的cpu核心數(shù)
fmt.Println("cpu核心數(shù):", cpuNum)
runtime.GOMAXPROCS(cpuNum) //設(shè)置需要用到的cpu數(shù)量
}運行結(jié)果如下:
cpu核心數(shù): 4
當前題目:創(chuàng)新互聯(lián)GO教程:Go語言多核并行化
轉(zhuǎn)載源于:http://m.5511xx.com/article/dhccpid.html


咨詢
建站咨詢
