這個問題探討了向現有 Go 程式引入並發時意外的效能下降。該程式碼模擬遊戲中與怪物的交互,追蹤成功的物品掉落。為了提高效率,程式設計師嘗試使用並發在可用處理器之間分配工作負載,但這導致速度顯著下降。
沒有並發,程式會執行一系列模擬(本例中為 1000),且每次模擬執行指定數量的交互作用(本例為 1,000,000)。然後將結果用於計算成功互動的總數。
為了並行化程式碼,程式設計師創建多個 goroutine,每個 goroutine 負責運行一部分模擬。它們正確地將工作負載分配給可用的 CPU,將 goroutine 的數量與處理器的數量相符。
令人驚訝的是,並發程式碼不但沒有提高效能,反而運行了 4-6 次比順序對應的慢。
問題在於共享狀態由並發 goroutine 存取。具體來說,rand.Float64() 函數使用具有關聯互斥鎖的共享全域 Rand 實例。當多個 goroutine 嘗試存取全域 Rand 實例時,它們必須取得互斥鎖,導致爭用並減慢程式碼速度。
為了解決效能問題,程式設計師建立了一個每個 goroutine 都有單獨的 Rand 實例。這消除了對全域 Rand 實例的爭用,允許 goroutine 獨立運作。
為每個 goroutine 建立單獨的 Rand 實例可顯著提高效能。現在,並發程式碼在雙核心 CPU 上的運行速度比非並發版本快約 2.5 倍。
此場景示範了了解共享資源使用的同步機制的重要性實現並發時。它強調了資料存取模式對效能的影響以及考慮處理器利用率和同步開銷之間權衡的需要。
以上是為什麼我的並發 Go 程式碼比其對應的串列程式碼慢?的詳細內容。更多資訊請關注PHP中文網其他相關文章!