為什麼說執行緒太多,cpu切換執行緒會浪費很多時間?

2022-02-03 22:09:25 字數 1643 閱讀 4180

更正:

問題1:

假如有乙個計算任務,計算1-100的和,每10個數相加,需要占用乙個cpu時間片(1s)。如果起乙個執行緒(模擬沒有執行緒切換),完成任務需要多長時間?如果起5個執行緒,完成任務需要消耗多久時間?如果起20個執行緒,完成任務需要多長時間?如果起20個執行緒呢?20個執行緒呢?50個執行緒呢?

假設1:cpu是單核cpu

假設2:每個執行緒的優先順序一樣。

假設3:cpu在兩個執行緒之間切換的時間消耗是0.1s。

答:1.如果起1個執行緒(模擬沒有執行緒切換)就要消耗10s的cpu時間能完成任務。

2.如果起5個執行緒,每個執行緒處理20個數相加,所以要占用2個cpu時間片,即10s,cpu要切換9次,即0.9s,總耗時10s+0.9s=10.9s;

3.如果起10個執行緒,每個執行緒處理10個數相加,要消耗1個cpu時間,即10s,cpu要切換9次,即0.9s,總耗時10s+0.9s=10.9s。

4.如果起20個執行緒,每個執行緒處理5個數相加,占用0.5個時間片,即消耗10s,cpu要切換19次,即1.9s,總耗時10s+1.9s=11.9s。

5.如果起50個執行緒,每個執行緒處理2個數相加,占用0.2個時間片,即消耗10s,cpu要切換50次,即5s,總耗時10s+5s=15s。

總結:1個執行緒最快,起5個執行緒和10個執行緒的耗時是一樣的,20個執行緒會更慢,所以執行緒數不是越多越好。

問題2:

假如有乙個計算任務,計算1-100的和,每10個數相加,需要占用乙個cpu時間片(1s),同時要在本地檔案(模擬io阻塞)記一次數,會阻塞2s。如果起1個執行緒,完成任務需要耗時多少?如果起5個執行緒,完成任務需要消耗多久時間?如果起10個執行緒,完成任務需要多長時間?如果起20個執行緒呢?50個執行緒呢?

假設1:cpu是單核cpu

假設2:每個執行緒的優先順序一樣。

假設3:cpu在兩個執行緒之間切換的時間消耗是0.1s。

答:1.如果起1個執行緒(模擬沒有執行緒切換)處理數字相加需要消耗10s,寫檔案(阻塞)要消耗20s,總共需要消耗10s+20s=30s。

3.如果起10個執行緒,每個執行緒處理10個數相加,要消耗1個cpu時間,即10s,cpu要切換9次,即0.9s,第一輪耗時10s+9s=10.9s;第二輪因為是io阻塞,直接切換,要切換10次,切換耗時1s,然後繼續等待第五個執行緒的io完成,等待1s(io要2s,切換執行緒過了1s,2-1=1)即可;所以總耗時是10.9s+1s+1s=12.9s。

4.如果起20個執行緒,每個執行緒處理5個數相加,第一輪切換29次執行緒,切換占用2.9s,計算數字需要10s,每切換兩個執行緒,就io阻塞一次,ios阻塞10次,最後一次切換執行緒之後,還要等待最後乙個執行緒的io,要等待2s。所以一共耗時2.9s+10s+2s=14.9s。

5.如果起50個執行緒,每個執行緒處理2個數相加,第一輪切換49次執行緒,切換占用4.9s,每切換5次執行緒,就io阻塞一次,計算數字要10s,,最後一次切換執行緒之後,還要等待最後乙個執行緒的io,要等待2s。所以總耗時是:4.9s+10s+2s=16.9s。

總結:1個執行緒最快,起5個執行緒和10個執行緒的耗時是一樣的,20個執行緒會更慢,所以執行緒數不是越多越好。

以下附上兩個自己畫的圖,便於理解:

為什麼協程切換的代價比執行緒切換低

先說結論 協程切換比執行緒切換快主要有兩點 1 協程切換完全在使用者空間進行,執行緒切換涉及特權模式切換,需要在核心空間完成 2 協程切換相比執行緒切換做的事情更少。協程切換只涉及基本的cpu上下文切換,所謂的 cpu 上下文,就是一堆暫存器,裡面儲存了 cpu執行任務所需要的資訊 從 開始執行 r...

為什麼有人說 Python 多執行緒是雞肋?

為什麼有人會說 python 多執行緒是雞肋?知乎上有人提出這樣乙個問題,在我們常識中,多程序 多執行緒都是通過併發的方式充分利用硬體資源提高程式的執行效率,怎麼在 python 中反而成了雞肋?有同學可能知道答案,因為 python 中臭名昭著的 gil,gil 是什麼?為什麼會有 gil?多線 ...

為什麼說Redis單執行緒效率高

redis效率高的主要原因有下面幾個 redis採用的是基於記憶體的採用的是單程序單執行緒模型的 kv 資料庫,由c語言編寫,官方提供的資料是可以達到100000 的qps 每秒內查詢次數 這個資料不比採用單程序多執行緒的同樣基於記憶體的 kv 資料庫 memcached 差!上圖是redis官方的...