簡體   English   中英

為什么我的並行任務代碼不能達到 100% 的 CPU 利用率?

[英]Why can't I reach 100% CPU utilization with my parallel tasks code?

private static async Task<int> SumParallel()
        {
            var intList = Enumerable.Range(1, 1000_000_000);
            int count = intList.Count();
            int total = 0;
            for(int i = 1; i < 5; i++)
            {
                int skip = ((i - 1) * count) / 4;
                int take = count / 4;
                Interlocked.Add(ref total,
                    await GetSum(intList, skip, take));
            }
            return total;
        }

private static async Task<int> GetSum(IEnumerable<int> list, int skip, int take)
        {
            return await Task.Run(() =>
             {
                 int temp = 0;
                 foreach(int n in list.Skip(skip).Take(take))
                 {
                     if (n % 2 == 0)
                         temp -= n;
                     else
                         temp += n;
                 }
                 return temp;
             });
        }

我正在嘗試執行計算密集型任務,只是為了練習任務並行庫。 所以,我寫了這段代碼。 如果我嘗試使用 Parallel Linq 計算相同的總和,我可以看到 CPU 利用率達到 100%,如下所示:

int sum = Enumerable.Range(1, 1000_000_000)
                .AsParallel()
                .Select(i => i % 2 == 0 ? -i : i).Sum();

手動並行任務代碼 = 10 秒時間,cpu = 僅 25%

並行 Linq 代碼 = 18 秒時間,cpu = 100%(仍然需要 18 秒)

Linq 代碼無並行:14 秒,僅 cpu = 25%

為什么會這樣? 當我同時啟動 4 個線程時,為什么我的 CPU 利用率沒有達到 100%? 與非並行代碼(只有一個線程)相比,它只有 25%。 我真的並行運行 4 個線程嗎?

我的筆記本電腦是 Core i3 - 2 個核心 = 4 個邏輯處理器

SumParallel沒有做並行工作,因為它按順序創建並等待每個任務:

for(int i = 1; i < 5; i++) {
    //...
    await GetSum(intList, skip, take)

要使其並行,您必須啟動所有五個任務,然后使用await await Task.WhenAll(tasks);等待所有任務完成。 .

至於並行 Linq 比標准 Linq 慢,這是因為您的工作負載太細了。 結果,並行性的開銷抵消了並行執行的任何好處。 換句話說,將項目分配給線程並收集結果比實際計算 ( n % 2 ) 更多的工作。 為了充分利用並行性,您的工作量必須很大。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM