創建多少線程纔是合適的

首先,我們要搞懂兩個問題:

  1. 爲什麼要使用多線程?
  2. 多線程的應用場景有哪些?

♣ 爲什麼要使用多線程?

使用多線程本質上是提升程序性能。那麼衡量性能的指標又包括哪些?

  1. 延遲:延遲是指發出請求到收到響應這個過程的時間。延遲越短,意味着程序執行的越快,性能越好。
  2. 吞吐量:吞吐量指的是單位時間內能處理請求的數量。吞吐量越大,意味着程序能處理的請求越多,性能越好。

我們所謂提升性能,主要是降低延遲,提高吞吐量。要想實現這個目的,先要了解多線程的使用場景。

♣ 多線程的應用場景

在併發編程領域,提升性能本質就是提升硬件的利用率,也就是提升 I/O 和 CPU 利用率。操作系統解決硬件利用率問題的對象往往是單一硬件設備,而併發程序往往需要 CPU 和 I/O 設備相互配合工作,所以我們要考慮 CPU 和 I/O 設備綜合利用率的問題。

下面我們看看多線程是如何提升 CPU 和 I/O 利用率的。假設程序按照 CPU 計算和 I/O 操作交叉執行的方式運行,而且 CPU 計算和 I/O 操作的耗時是 1:1.

如圖,當只有一個線程,執行CPU計算時,I/O設備空閒;執行I/O操作時,CPU空閒。所以兩者利用率都是50%。
                  在這裏插入圖片描述
如果又增加一個線程,如圖,線程A執行 CPU 計算時,線程B執行 I/O 操作;線程B執行 CPU 計算時,線程A執行 I/O 操作;這樣 CPU 和 I/O 設備的利用率就達到了 100%。
                 在這裏插入圖片描述
剛剛我們將 CPU 和 I/O 設備的利用率都提升到了100%,單位時間處理的請求數量翻了一倍,也就是說吞吐量提高了1倍。反過來想:如果CPU 和 I/O 設備的利用率都很低,那麼可以嘗試通過增加線程來提高吞吐量

單核CPU時代,多線程主要是用力啊平衡 CPU 和 I/O 設備的。如果程序只有CPU計算,而沒有I/O操作,多線程不會使性能提升反而會下降,原因是多線程增加了線程切換的成本。不過在多核時代,這種純計算型的場景可以利用多線程提升性能,因爲利用多核可以降低響應時間。

舉個例子:
計算 1+2+…+100億的值,如果用4核CPU的程序執行,A線程計算(1,25億),B線程計算(25億,50億),C線程計算(50億,75億),D線程計算(75億,100億),最後彙總。這樣理論上會比一個線程計算[1,100億]快4倍左右,響應時間能夠降低到25%。一個線程,對於4核的CPU,利用率只有25%,而4個線程,則能夠將CPU的利用率提高到100%。

                 在這裏插入圖片描述

♣ 創建多少線程合適?

創建多少線程纔是合適的,要看多線程具體的應用場景。一般有兩種情況:

  1. I/O密集型
  2. CPU密集型

I/O密集型程序和CPU密集型程序,計算最佳線程數的方法不同。
下面我們分開來說。

♠ CPU密集型

對於CPU密集型計算,多線程本質上是提升CPU的利用率,所以對於一個4核的CPU,每個核一個線程,理論上創建4個線程就可以了,再多創建線程也只會增加線程切換成本。所以,對於CPU密集型的計算場景,理論上“線程數量 = CPU 核數”就是最合適的。不過實際應用中,線程數量一般會設置爲“CPU核數 + 1" ,這樣的話,當線程因爲偶爾的內存頁失效或其他原因導致阻塞時,這個額外的線程可以頂上,從而保證CPU利用率。

♠ I/O密集型

對於I/O密集型的計算場景,比如前面的例子中,如果 CPU 計算和 I/O 操作的耗時是1:1,那麼2個線程是最合適的。如果 CPU 計算和 I/O 操作的耗時是1:2,那多少個線程合適呢?是3個線程,如圖所示:CPU在A、B、C三個線程之間切換,對於線程A,當CPU 從B、C線程切換回來時,線程A正好執行完I/O操作。這樣 CPU 和 I/O 設備的利用率都達到了100%。
                 在這裏插入圖片描述
通過上面這個例子,我們發現,對於I/O 密集型計算場景,最佳線程數是與程序中CPU計算和I/O操作的耗時比相關的。
可以總結一個公式:最佳線程數 = 1 + (I/O 耗時 / CPU耗時)

我們令 R = I/O 耗時 / CPU耗時,綜合上圖,可以理解成:當線程A執行IO操作時,另外 R 個線程正好執行完各自的CPU計算。這樣CPU利用率就達到了100%。

對於多核CPU,等比擴大即可:最佳線程數 = CPU核數 * [ 1 + (I/O 耗時 / CPU耗時)]

有收穫的話,點個贊吧~

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章