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

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

如何決定并發操作的數量?

如何決定并發操作的數量?

Go
海綿寶寶撒 2022-05-10 14:11:59
我目前正在編寫一個編碼器,并且(顯然)想讓它變得更快。我有一個工作系統來進行編碼(所以每個 goroutine 都在做同樣的事情),但我正在努力尋找合適數量的 goroutine 來運行代碼。我基本上想決定保持最大數量的 Goroutines CPU 忙。下面的想法掠過我的腦海:如果一個文件只有 <1 kB,那么在很多 goroutine 中運行代碼是沒有用的goroutines 的數量應該受可用的核心/線程的影響在 4x4 GHz CPU 上運行 16 個 goroutine 不會有問題,但在 4x1 GHz CPU 上呢?難以確定可靠的跨平臺CPU 應該很忙,但不要忙到阻止其他程序響應(~70-ish %?)由于時鐘速度和其他參數,很難事先決定現在我嘗試根據這些因素來決定使用多少個 goroutine,但我不太確定如何跨平臺并以可靠的方式這樣做。已經嘗試過:使用線性函數根據文件大小確定需要基于 CPU 的不同功能從 lscpu 解析 CPU 規格不跨平臺需要另一個函數來根據頻率確定這并不令人滿意。
查看完整描述

1 回答

?
長風秋雁

TA貢獻1757條經驗 獲得超7個贊

你在評論中提到


每個 goroutine 都在讀取要編碼的文件


但當然,文件——任何文件——已經以某種方式編碼:也許是純文本,或者是 UTF-8(字節流),也許是組裝成“行”單元。或者它可能是一個圖像流,例如一個 mpeg 文件,由一些幀組成。或者它可能是一個由記錄組成的數據庫。無論其輸入形式是什么,它都包含某種基本單元,您可以將其提供給您的(重新)編碼器。


那個單位,不管它是什么,都是一個合理的分工場所。(多么明智,取決于它是什么。請參閱下面的分塊的想法。)


假設文件由獨立的行組成:然后使用scanner.Scan來讀取它們,并將每一行傳遞給一個接收行的通道。分拆 N,對于一些 N,閱讀頻道的讀者,一次一行:


ch := make(chan string)

for i := 0; i < n; i++ {

    go readAndEncode(ch)

}


// later, or immediately:

for s := bufio.NewScanner(os.Stdin); s.Scan(); {

    ch <- s.Text()

}

close(ch)

如果有 100 行和 4 個閱讀器,前四個ch <- s.Text()操作會快速進行,第五個操作會暫停,直到其中一個閱讀器完成編碼并返回讀取通道。


如果單個行太小,也許您應該一次讀取一個“塊”(例如,1 MB)。如果塊的末尾有部分行,請備份或閱讀更多內容,直到您有整行。然后發送整個數據塊。


因為通道復制數據,您可能希望發送對塊的引用。1 這適用于任何更大的數據單元。(行往往很短,與首先使用通道的開銷相比,復制它們的開銷通常不是很大。如果你的行有 type string,那么,請參閱腳注。)


如果行或行塊在這里不是正確的工作單元,請弄清楚什么是. 將 goroutine 想象為每個人都有一份工作要做的人(或忙碌的小地鼠) 。他們可以依靠其他人——另一個人或地鼠——來做一份較小的工作,不管那是什么;并且有十個人,或稱地鼠,處理子任務允許主管管理它們。如果你需要做 N 次相同的工作,并且 N 不是無界的,你可以分拆 N 個 goroutine。如果 N可能是無界的,則分拆一個固定的數字(可能基于#cpus)并通過通道為它們提供工作。


1正如 Burak Serdar 所指出的,一些副本可以自動刪除:例如,字符串實際上是只讀切片。切片類型包含三個部分:指向底層數據的指針(引用)、長度和容量。復制切片會復制這三個部分,但不會復制底層數據。字符串也是如此:字符串標題省略了容量,因此通過通道發送字符串僅復制兩個標題詞。因此,許多明顯且易于編碼的數據分塊方式已經非常有效。


查看完整回答
反對 回復 2022-05-10
  • 1 回答
  • 0 關注
  • 135 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

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

幫助反饋 APP下載

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

公眾號

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