溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Go 語言中如何利用多核 CPU 實現(xiàn)并行計算

發(fā)布時間:2021-11-15 15:27:23 來源:億速云 閱讀:220 作者:柒染 欄目:大數(shù)據

本篇文章給大家分享的是有關Go 語言中如何利用多核 CPU 實現(xiàn)并行計算,小編覺得挺實用的,因此分享給大家學習,希望大家閱讀完這篇文章后可以有所收獲,話不多說,跟著小編一起來看看吧。

開始之前,我們先澄清兩個概念,「多核」指的是有效利用 CPU 的多核提高程序執(zhí)行效率,「并行」和「并發(fā)」一字之差,但其實是兩個完全不同的概念,「并發(fā)」一般是由 CPU 內核通過時間片或者中斷來控制的,遇到 IO 阻塞或者時間片用完時會交出線程的使用權,從而實現(xiàn)在一個內核上處理多個任務,而「并行」則是多個處理器或者多核處理器同時執(zhí)行多個任務,同一時間有多個任務在調度,因此,一個內核是無法實現(xiàn)并行的,因為同一時間只有一個任務在調度。

多進程、多線程以及協(xié)程顯然都是屬于「并發(fā)」范疇的,可以實現(xiàn)程序的并發(fā)執(zhí)行,至于是否支持「并行」,則要看程序運行系統(tǒng)是否是多核,以及編寫程序的語言是否可以利用 CPU 的多核特性。

下面我們以 goroutine 為例,來演示如何在 Go 語言中通過協(xié)程有效利用「多核」實現(xiàn)程序的「并行」執(zhí)行,具體實現(xiàn)的話就是根據系統(tǒng) CPU 核心數(shù)量來分配等值的子協(xié)程數(shù),讓所有協(xié)程分配到每個內核去并行執(zhí)行。要查看系統(tǒng)核心數(shù),以 MacOS 為例, 可以通過 sysctl hw 命令分別查看物理 CPU 和邏輯 CPU 核心數(shù):

Go 語言中如何利用多核 CPU 實現(xiàn)并行計算

我的系統(tǒng)物理 CPU 核心數(shù)是 4 個,邏輯 CPU 核心數(shù)是 8 個,所謂物理 CPU 核心數(shù)指的是真正插在物理插槽上 CPU 的核心數(shù),邏輯 CPU 核心數(shù)指的是結合 CPU 多核以及超線程技術得到的 CPU 核心數(shù),最終核心數(shù)以邏輯 CPU 核心數(shù)為準。

此外,你也可以在 Go 語言中通過調用 runtime.NumCPU() 方法獲取 CPU 核心數(shù)。

接下來,我們來模擬一個可以并行的計算任務:啟動多個子協(xié)程,子協(xié)程數(shù)量和 CPU 核心數(shù)保持一致,以便充分利用多核并行運算,每個子協(xié)程計算分給它的那部分計算任務,最后將不同子協(xié)程的計算結果再做一次累加,這樣就可以得到所有數(shù)據的計算總和。我們編寫對應的示例文件 parallel.go

package main
import (    "fmt"    "runtime"    "time")
func sum(seq int, ch chan int) {    defer close(ch)    sum := 0    for i := 1; i <= 10000000; i++ {        sum += i    }    fmt.Printf("子協(xié)程%d運算結果:%d\n", seq, sum)    ch <- sum}
func main()  {    // 啟動時間    start := time.Now()    // 最大 CPU 核心數(shù)    cpus := runtime.NumCPU()    runtime.GOMAXPROCS(cpus)    chs := make([]chan int, cpus)    for i := 0; i < len(chs); i++ {        chs[i] = make(chan int, 1)        go sum(i, chs[i])    }    sum := 0    for _, ch := range chs {        res := <- ch        sum += res    }    // 結束時間    end := time.Now()    // 打印耗時    fmt.Printf("最終運算結果: %d, 執(zhí)行耗時(s): %f\n", sum, end.Sub(start).Seconds())}    

這里我們通過 runtime.NumCPU() 獲取邏輯 CPU 核心數(shù),然后通過 runtime.GOMAXPROCS() 方法設置程序運行時可以使用的最大核心數(shù),這里設置為和系統(tǒng) CPU 核心數(shù)一致,然后初始化一個通道數(shù)組,數(shù)量和 CPU 核心數(shù)保持一致,以便充分利用多核實現(xiàn)并行計算,接下來就是依次啟動子協(xié)程進行計算,并在子協(xié)程中計算完成后將結果數(shù)據發(fā)送到通道中,最后在主協(xié)程中接收這些通道數(shù)據并進行再次累加,作為最終計算結果打印出來,同時計算程序運行時間作為性能的考量依據。

此時,我們運行 parallel.go,得到的結果如下:

Go 語言中如何利用多核 CPU 實現(xiàn)并行計算

然后我們修改 runtime.GOMAXPROCS() 方法中傳入的 CPU 核心數(shù)為 1,再次運行 parallel.go,得到的結果如下:

Go 語言中如何利用多核 CPU 實現(xiàn)并行計算

可以看到使用多核比單核整體運行速度快了4倍左右,查看系統(tǒng) CPU 監(jiān)控也能看到所有內核都被打滿,這在 CPU 密集型計算中帶來的性能提升還是非常顯著的,不過對于 IO 密集型計算可能沒有這么顯著,甚至有可能比單核低,因為 CPU 核心之間的切換也是需要時間成本的,所以 IO 密集型計算并不推薦使用這種機制,什么是 IO 密集型計算?比如數(shù)據庫連接、網絡請求等。

另外,需要注意的是,目前 Go 語言默認就是支持多核的,所以如果上述示例代碼中沒有顯式設置 runtime.GOMAXPROCS(cpus) 這行代碼,編譯器也會利用多核 CPU 來執(zhí)行代碼,其結果是運行耗時和設置多核是一樣的。

以上就是Go 語言中如何利用多核 CPU 實現(xiàn)并行計算,小編相信有部分知識點可能是我們日常工作會見到或用到的。希望你能通過這篇文章學到更多知識。更多詳情敬請關注億速云行業(yè)資訊頻道。

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI