原文:https://chanjarster.github.io...html
如今有一個task,它的執行時間分爲2部分,第一部分作數學運算,第二部分等待IO。這兩部分就是所謂的計算操做與等待操做。git
那麼如今要求估算在CPU火力全開的狀況下,執行這個task可以達到的吞吐量峯值是多少?github
那麼咱們要先知道執行這個task總共須要多少時間,計算部分花費多少時間,等待部分花費多少時間。ide
假設這個task的計算部分花費1秒,等待部分花費9秒,而且開了10個線程執行10個task,在單核CPU的狀況下能夠獲得下面的執行圖:post
圖中的藍色線條是等待調度,橙色線條是執行計算任務,綠色線條是CPU等待花費的時間。性能
能夠得益於開了10個線程,每一個task能夠利用其餘task的等待時間裏執行本身的計算操做,同時使得CPU始終處於忙碌狀態,即利用率100%。這也告訴你,就算你開11個線程也不會獲得更多好處。spa
上面這個圖的計算任務是按順序執行的,這只是一個假想狀況,實際中操做系統會將這10個線程交替運行,見圖中的紅色線,操做系統能夠在這個範圍內對這10個task的計算任務作任意調度。若是去除線程調度的開銷,花費的總時間其實仍是等於10秒的。操作系統
這個圖的吞吐量就顯而易見了:線程
throughput = 10 tasks / (10 * computing time + wait time) = 10 tasks / (10 * 1s + 9s) = 10 / 19s = 0.526 tasks/s
若是咱們如今有一個雙核CPU,那麼會怎樣呢?3d
能夠看到由於有了2個CPU核心,計算任務能夠重疊,進而花費的時間減半,吞吐量爲:
throughput = 10 tasks / (10 * computing time / 2 + wait time) = 10 tasks / (10 * 1s / 2 + 9s) = 10 / 14s = 0.7142 tasks/s
那麼總結一下吞吐量計算公式:
公式中C=1的意思是CPU 100%的全速工做,若是C=0.5那麼意思就是CPU有50%的空閒時間,若是C=2則表明啓動了兩顆CPU全速運行。
能夠看到想要提高吞吐量有:
總的來講就是使用更多的CPU核,讓task運行時間更短。
也許你以爲還能夠經過提高Tn來提升吞吐量,好比下面這個圖:
能夠看到吞吐量隨着任務數量的上升而上升,那麼是否是會一直長呢?答案是不會的,當Tn愈來愈大的時候,Tn * Tc / C 也會愈來愈大,那麼能夠忽略掉Tw,公式就變成了 C / Tc,這值就是理論上的吞吐量上界,增長Tn只會無限趨近於這個值。
那麼問題來了,如何知道要開多少個線程可以讓CPU達到目標利用率?
這個要看下面的公式:
注:本公式裏的 N * U = 吞吐量公式中的C。
若是U=1(利用率100%),決定線程數量的是W與C的比,當W越高時則須要越多的線程,當W=0時,只須要與N一樣的線程便可。
這個公式也告訴咱們開啓更多的線程不會帶來額外的好處,還會形成反效果(增長的線程調度開銷),因此在實踐中都會使用具備上界的線程池。
並且在實際作性能調優的時候,會在計算獲得的數字左右調整線程池大小,以達到最好效果。