前言:博主最近在比較python和go語言寫的web伺服器的執行效率問題,在看了google搜尋結果後,產生了疑問
1.為什麼python的非同步執行框架tornado效率可以和go語言媲美?
2.為什麼隨著執行緒的增加,併發數的增長呈現逐步緩慢的趨勢?
注意:為簡化推理過程和理解,以下只考慮執行任務的執行緒,系統中其他所有(包括系統執行緒)均不考慮,即cpu只執行我們的任務執行緒。
一、單核cpu
首先,我們要知道在單核時,只能進行併發執行某個執行緒(作業系統的時間片輪轉法是分配時間片給執行緒而不是程序,博主有文章提到過),而不能並行執行。
1.當執行緒為cpu密集型時( 比如乙個 while( true ) )
(圖中橫座標是時間,從0s到1s,方塊是執行緒每次時間片的執行)
由於時間片輪轉,雖然cpu中只有這乙個執行緒在執行,可它還是每執行乙個時間片後就被排程出cpu,再排程回來,這樣在1s內時間被用來執行執行緒+排程執行緒,cpu一直在執行執行緒和排程,利用率為100%(看吧,我們單執行緒就把cpu跑滿了),此時如果增加執行緒,執行效率不會得到提公升,反而可能因為排程變複雜、記憶體等資源爭奪而降低效率!
2.當執行緒為io密集型時(比如乙個從磁碟拷貝資料到另乙個磁碟的拷貝程序)
(圖中橫軸為時間,從0s到1s,方塊為執行緒占用cpu執行,波浪線為執行緒正在io(此時cpu為空),該執行緒只有io結束才能繼續執行,波浪線與方塊之間的時間為排程時間)
從圖中可以發現,cpu利用率極低,1s內時間被用來執行執行緒+io+排程,此時如果對當前任務用多執行緒,只要磁碟足夠快,那理論上1s內cpu利用率越高,效率越高,但是實際上磁碟讀寫速度有限,如果增加過多執行緒,cpu利用率是上去了,但是磁碟因為要切換多個執行緒的讀寫(由於執行緒被排程),導致效率降低,木桶效應,影響整個任務效率。
3.當執行執行緒為計算多,io少(其實本質就是計算密集型比如乙個web伺服器,執行各種數**算並返回結果)
此時若採用單執行緒,那圖和2中類似,只不過方塊變大,波浪變小;
此時若採用多執行緒,比如兩個執行緒時
(如圖,方塊間為cpu排程時間,波浪線為io時間)
從圖中,因為io少,我們考慮此時磁碟肯定後於cpu滿載,所以隨著執行緒的增加,cpu利用率變高,理想狀態下,1s時間被用來執行執行緒+排程,此時io和執行並行了,極大提高了cpu利用率,因而可知,cpu密集而io少的執行緒合理使用多執行緒可以增加cpu使用率和任務執行效率,至於多少個執行緒合適,則應在實際的硬體和系統下進行測試。
4.當執行緒為cpu執行少,io多時(其實本質就是io密集型,比如乙個從磁碟拷貝資料到另乙個磁碟的拷貝程序)
參考2,方塊變更小了,波浪更長了,此時執行效率同樣受制於磁碟,若磁碟未滿載,則繼續增加執行緒可以增加cpu使用率和磁碟使用率,加快任務效率,但若磁碟滿載,則繼續增加執行緒整體執行效率反而降低。
二、多核cpu
以八核為例,
1)若只跑乙個執行緒,那同一時間只有某一核被利用,其他七核都空閒;
2)若同時跑八個計算密集型,則理論上整個任務執行效率會提高八倍,若超過八個執行緒,則效率可能反而下降;
3)若同時跑八個io密集型,若沒超過磁碟負載,則還可以繼續增加執行緒,同時執行效率得到提高,若超過了,則執行效率會急劇下降;
注意:以上io密集和cpu密集只是舉例子,密不密集不是靠個人感覺,計算量大不大也不是靠個人感覺,實際上,例子中io密集執行緒代表的情況是:使在cpu滿載前,磁碟先滿載的執行緒;cpu密集執行緒代表的情況是:使磁碟滿載前,cpu先滿載的執行緒;
舉個例子:乙個執行緒要就算圓周率後一百億億位,由於記憶體只有1g,所以要不斷把中間結果寫回磁碟在某台cpu差,硬碟讀寫速度超級高的裝置上(外星人的科技,讀寫速度為無窮大),是cpu密集型;在另一台運算超級厲害的cpu(也是外星人科技,計算圓周率後一百億億位只要1ms的那種),然而磁碟卻很慢(1kb/s),那它反而變成了io密集型
現在大家說的io密集型和cpu密集型是針對21世紀的大眾硬體來說的,雖然沒那麼極端,但是還是想讓大家知道,要具體問題具體分析,io密集和cpu密集也只是相對的,而且要判斷多執行緒能否提高執行效率,首先要知道這個執行緒在執行任務的機器上是io密集型還是cpu密集型
關於多執行緒在多核cpu上執行效率的問題
前言 博主最近在比較python和go語言寫的web伺服器的執行效率問題,在看了google搜尋結果後,產生了疑問 1.為什麼python的非同步執行框架tornado效率可以和go語言媲美?2.為什麼隨著執行緒的增加,併發數的增長呈現逐步緩慢的趨勢?注意 為簡化推理過程和理解,以下只考慮執行任務的...
多執行緒程式在多核和單核上執行的不同
1 鎖 在單核上,多個執行緒執行鎖或者臨界區時,實際上只有乙個執行緒在執行臨界區 而核心也只支援乙個執行緒執行,因此不存在衝突。如果某個執行緒持有鎖,那只有其他執行緒不會被排程到cpu上執行,影響的只是持有和釋放鎖的時間,處理器時刻在執行著。但是在多核上執行時,鎖或臨界區會導致其餘處理器空閒而只允許...
多執行緒程式在多核和單核上執行的不同
1.單核cpu 同一時間,cpu只能處理1個執行緒,只有1個執行緒在執行 2.多執行緒同時執行 是cpu快速的在多個執行緒之間的切換 3.cpu排程執行緒的時間足夠快,就造成了多執行緒的 同時 執行 4.如果執行緒數非常多,cpu會在n個執行緒之間切換,消耗大量的cpu資源 5.每個執行緒被排程的次...