亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

不同輸入數據的 Goroutine 執行時間

不同輸入數據的 Goroutine 執行時間

Go
繁花不似錦 2021-08-23 17:54:15
我正在嘗試使用 goroutine 來并行化一些計算。但是,goroutine 的執行時間讓我很困惑。我的實驗設置很簡單。runtime.GOMAXPROCS(3)datalen := 1000000000data21 := make([]float64, datalen)data22 := make([]float64, datalen)data23 := make([]float64, datalen)t := time.Now()res := make(chan interface{}, dlen)go func() {    for i := 0; i < datalen; i++ {        data22[i] = math.Sqrt(13)    }    res <- true}()go func() {    for i := 0; i < datalen; i++ {        data22[i] = math.Sqrt(13)    }    res <- true}()go func() {    for i := 0; i < datalen; i++ {        data22[i] = math.Sqrt(13)    }    res <- true}()for i:=0; i<3; i++ {    <-res}fmt.Printf("The parallel for loop took %v to run.\n", time.Since(t))請注意,我在 3 個 goroutine 中加載了相同的數據,該程序的執行時間為The parallel for loop took 7.436060182s to run.但是,如果我讓每個 goroutine 處理不同的數據,如下所示:runtime.GOMAXPROCS(3)datalen := 1000000000data21 := make([]float64, datalen)data22 := make([]float64, datalen)data23 := make([]float64, datalen)t := time.Now()res := make(chan interface{}, dlen)go func() {    for i := 0; i < datalen; i++ {        data21[i] = math.Sqrt(13)    }    res <- true}()go func() {    for i := 0; i < datalen; i++ {        data22[i] = math.Sqrt(13)    }    res <- true}()go func() {    for i := 0; i < datalen; i++ {        data23[i] = math.Sqrt(13)    }    res <- true}()for i:=0; i<3; i++ {    <-res}fmt.Printf("The parallel for loop took %v to run.\n", time.Since(t))這個的執行時間幾乎是之前的 3 倍,幾乎等于/比沒有 goroutine 的順序執行更糟The parallel for loop took 20.744438468s to run.我想也許我以錯誤的方式使用了 goroutine。那么使用多個 goroutine 處理不同數據的正確方法應該是什么?
查看完整描述

2 回答

?
幕布斯7119047

TA貢獻1794條經驗 獲得超8個贊

由于您的示例程序沒有執行任何實質性的計算,瓶頸將是數據寫入內存的速度。使用示例中的設置,我們討論的是 22 GB 的寫入,這并不是無關緊要的。

鑒于兩個示例的運行時間存在時間差異,一種可能的可能性是它實際上沒有向 RAM 寫入那么多。鑒于內存寫入由 CPU 緩存,執行可能如下所示:

  1. 第一個 goroutine 將數據寫入表示data22數組開頭的緩存行。

  2. 第二個 goroutine 將數據寫入表示相同位置的緩存行。運行第一個 goroutine 的 CPU 注意到寫入使自己緩存的寫入無效,因此丟棄其更改。

  3. 第三個 goroutine 將數據寫入表示相同位置的緩存行。運行第二個 goroutine 的 CPU 注意到寫入使自己緩存的寫入無效,因此丟棄其更改。

  4. 第三個 CPU 中的緩存行被逐出,并將更改寫出到 RAM。

這個過程隨著 goroutine 在data22數組中的進展而繼續。由于 RAM 是瓶頸,在這種情況下我們最終寫入的數據量是后者的三分之一,因此它的運行速度大約是第二種情況的 3 倍也就不足為奇了。


查看完整回答
反對 回復 2021-08-23
?
心有法竹

TA貢獻1866條經驗 獲得超5個贊

您正在使用大量內存。在第一個示例中 1000000000 * 8 = 8GB,在第二個示例中 3 * 1000000000 * 8 = 24GB。在第二個示例中,您可能使用了大量交換空間。磁盤 I/O 非常非常慢,即使在 SSD 上也是如此。

將 datalen := 1000000000 更改為 datalen := 100000000,減少 10 倍。你現在的運行時間是多少?每個示例至少平均運行 3 次。你的電腦有多少內存?你用的是SSD嗎?


查看完整回答
反對 回復 2021-08-23
  • 2 回答
  • 0 關注
  • 221 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號