1. 程式人生 > >計算密集型&IO密集型

計算密集型&IO密集型

原文:http://www.liaoxuefeng.com/wiki/001374738125095c955c1e6d8bb493182103fac9270762a000/001397567993007df355a3394da48f0bf14960f0c78753f000

程序 vs. 執行緒

我們介紹了多程序和多執行緒,這是實現多工最常用的兩種方式。現在,我們來討論一下這兩種方式的優缺點。

首先,要實現多工,通常我們會設計Master-Worker模式,Master負責分配任務,Worker負責執行任務,因此,多工環境下,通常是一個Master,多個Worker。

如果用多程序實現Master-Worker,主程序就是Master,其他程序就是Worker。

如果用多執行緒實現Master-Worker,主執行緒就是Master,其他執行緒就是Worker。

多程序模式最大的優點就是穩定性高,因為一個子程序崩潰了,不會影響主程序和其他子程序。(當然主程序掛了所有程序就全掛了,但是Master程序只負責分配任務,掛掉的概率低)著名的Apache最早就是採用多程序模式。

多程序模式的缺點是建立程序的代價大,在Unix/Linux系統下,用fork呼叫還行,在Windows下建立程序開銷巨大。另外,作業系統能同時執行的程序數也是有限的,在記憶體和CPU的限制下,如果有幾千個程序同時執行,作業系統連排程都會成問題。

多執行緒模式通常比多程序快一點,但是也快不到哪去,而且,多執行緒模式致命的缺點就是任何一個執行緒掛掉都可能直接造成整個程序崩潰,因為所有執行緒共享程序的記憶體。在Windows上,如果一個執行緒執行的程式碼出了問題,你經常可以看到這樣的提示:“該程式執行了非法操作,即將關閉”,其實往往是某個執行緒出了問題,但是作業系統會強制結束整個程序。

在Windows下,多執行緒的效率比多程序要高,所以微軟的IIS伺服器預設採用多執行緒模式。由於多執行緒存在穩定性的問題,IIS的穩定性就不如Apache。為了緩解這個問題,IIS和Apache現在又有多程序+多執行緒的混合模式,真是把問題越搞越複雜。

執行緒切換

無論是多程序還是多執行緒,只要數量一多,效率肯定上不去,為什麼呢?

我們打個比方,假設你不幸正在準備中考,每天晚上需要做語文、數學、英語、物理、化學這5科的作業,每項作業耗時1小時。

如果你先花1小時做語文作業,做完了,再花1小時做數學作業,這樣,依次全部做完,一共花5小時,這種方式稱為單任務模型,或者批處理任務模型。

假設你打算切換到多工模型,可以先做1分鐘語文,再切換到數學作業,做1分鐘,再切換到英語,以此類推,只要切換速度足夠快,這種方式就和單核CPU執行多工是一樣的了,以幼兒園小朋友的眼光來看,你就正在同時寫5科作業。

但是,切換作業是有代價的,比如從語文切到數學,要先收拾桌子上的語文書本、鋼筆(這叫儲存現場),然後,開啟數學課本、找出圓規直尺(這叫準備新環境),才能開始做數學作業。作業系統在切換程序或者執行緒時也是一樣的,它需要先儲存當前執行的現場環境(CPU暫存器狀態、記憶體頁等),然後,把新任務的執行環境準備好(恢復上次的暫存器狀態,切換記憶體頁等),才能開始執行。總之,CPU給每個任務都服務一定的時間,然後把當前任務的狀態儲存下來,在載入下一任務的狀態後,繼續服務下一任務。任務的狀態儲存及再載入,這段過程就叫做上下文切換。時間片輪轉的方式使多個任務在同一顆CPU上執行變成了可能,但同時也帶來了儲存現場和載入現場的直接消耗。(Note. 更精確地說, 上下文切換會帶來直接和間接兩種因素影響程式效能的消耗. 直接消耗包括: CPU暫存器需要儲存和載入, 系統排程器的程式碼需要執行, TLB例項需要重新載入, CPU 的pipeline需要刷掉; 間接消耗指的是多核的cache之間得共享資料, 間接消耗對於程式的影響要看執行緒工作區操作資料的大小)。雖然這個切換過程很快,但是也需要耗費時間。如果有幾千個任務同時進行,作業系統可能就主要忙著切換任務,根本沒有多少時間去執行任務了,這種情況最常見的就是硬碟狂響,點視窗無反應,系統處於假死狀態。所以,多工一旦多到一個限度,就會消耗掉系統所有的資源,結果效率急劇下降,所有任務都做不好。

計算密集型 vs. IO密集型

是否採用多工的第二個考慮是任務的型別。我們可以把任務分為計算密集型和IO密集型。

計算密集型任務的特點是要進行大量的計算,消耗CPU資源,比如計算圓周率、對視訊進行高清解碼等等,全靠CPU的運算能力。這種計算密集型任務雖然也可以用多工完成,但是任務越多,花在任務切換的時間就越多,CPU執行任務的效率就越低,所以,要最高效地利用CPU,計算密集型任務同時進行的數量應當等於CPU的核心數。

計算密集型任務由於主要消耗CPU資源,因此,程式碼執行效率至關重要。Python這樣的指令碼語言執行效率很低,完全不適合計算密集型任務。對於計算密集型任務,最好用C語言編寫。

第二種任務的型別是IO密集型,涉及到網路、磁碟IO的任務都是IO密集型任務,這類任務的特點是CPU消耗很少,任務的大部分時間都在等待IO操作完成(因為IO的速度遠遠低於CPU和記憶體的速度)。對於IO密集型任務,任務越多,CPU效率越高,但也有一個限度。常見的大部分任務都是IO密集型任務,比如Web應用。

IO密集型任務執行期間,99%的時間都花在IO上,花在CPU上的時間很少,因此,用執行速度極快的C語言替換用Python這樣執行速度極低的指令碼語言,完全無法提升執行效率。對於IO密集型任務,最合適的語言就是開發效率最高(程式碼量最少)的語言,指令碼語言是首選,C語言最差。

非同步IO

考慮到CPU和IO之間巨大的速度差異,一個任務在執行的過程中大部分時間都在等待IO操作,單程序單執行緒模型會導致別的任務無法並行執行,因此,我們才需要多程序模型或者多執行緒模型來支援多工併發執行。

現代作業系統對IO操作已經做了巨大的改進,最大的特點就是支援非同步IO。如果充分利用作業系統提供的非同步IO支援,就可以用單程序單執行緒模型來執行多工,這種全新的模型稱為事件驅動模型,Nginx就是支援非同步IO的Web伺服器,它在單核CPU上採用單程序模型就可以高效地支援多工。在多核CPU上,可以執行多個程序(數量與CPU核心數相同),充分利用多核CPU。由於系統總的程序數量十分有限,因此作業系統排程非常高效。用非同步IO程式設計模型來實現多工是一個主要的趨勢。

相關推薦

計算密集型&IO密集型

原文:http://www.liaoxuefeng.com/wiki/001374738125095c955c1e6d8bb493182103fac9270762a000/001397567993007df355a3394da48f0bf14960f0c78753f000

執行緒與程序 計算密集型 IO密集型

執行緒與程序:   執行緒和程序通常都有一個主線/程序的負責分配任務和其他子線/程序負責執行任何。   多程序的優點在於一個子程序掛了,不會影響其他程序(主程序掛了就全掛了),但是其建立的代價較大,Apache採用的就是多程序機制;   而多執行緒一般要比

Python進階之CPU計算密集型IO密集型

在最近往伺服器部署爬蟲程式的時候,遇到了一個很奇怪的問題,就是部署上之後執行一段時間或者是直接不執行就進入休眠狀態了,開始一直懷疑是由於伺服器記憶體不足導致的程式休眠,後來廢了好大的勁,最終找到了罪魁禍首,具體分析我通過這幾篇連載的部落格來分析一下,正好也對給自己充充電。 第一種任務的型別是

計算密集型IO密集型、資料密集型

計算密集型(CPU-Intensive) 1、特點:要進行大量的計算,消耗CPU資源。比如計算圓周率、對視訊進行高清解碼等等,全靠CPU的運算能力。 2、計算密集型任務雖然也可以用多工完成,但是任務越多,花在任務切換的時間就越多,CPU執行任務的效率就越低,所以,要最高效地利用CPU,計算密

IO密集型計算密集型、執行緒和程序

io密集型:有阻塞的狀態,就是一直會執行CPU(中間就一個等待狀態,這個就叫做IO密集型)。例如:sleep狀態 計算密集型任務:沒有等待的狀態就是計算密集型,從上到下執行沒有等待。 在Python中沒法同時使用多個CPU,在同一時刻,多個執行緒是互相搶佔資源的,在cpython執行中加了一把鎖(GIL)

[Python]IO密集型任務 VS 計算密集型任務

IO密集型任務 VS 計算密集型任務 所謂IO密集型任務,是指磁碟IO、網路IO佔主要的任務,計算量很小。比如請求網頁、讀寫檔案等。當然我們在Python中可以利用sleep達到IO密集型任務的目的。 所謂計算密集型任務,是指CPU計算佔主要的任務,CPU一直處於滿負荷狀態。比如在一個很大的列

CPU io-密集型 計算密集型

核心是可以分別獨立執行程式指令的計算單元。 執行緒是作業系統能夠進行運算排程的最小單位。 有一個原則是:活躍執行緒數為 CPU(核)數時最佳。過少的活躍執行緒導致 CPU 無法被充分利用,過多的活躍執行緒導致過大的執行緒上下文切換開銷。 執行緒應該是活躍的,處於 IO 的

Python筆記-計算密集型(最好用C)、IO密集型(最好用指令碼)

計算密集型 1、特點:要進行大量的計算,消耗CPU資源。比如計算圓周率、對視訊進行高清解碼等等,全靠CPU的運算能力。 2、計算密集型任務雖然也可以用多工完成,但是任務越多,花在任務切換的時間就越多,CPU執行任務的效率就越低,所以,要最高效地利用CPU,計

計算密集型IO密集型

計算密集型 計算密集型任務的特點是要進行大量的計算,消耗CPU資源,比如計算圓周率、對視訊進行高清解碼等等,全靠CPU的運算能力。這種計算密集型任務雖然也可以用多工完成,但是任務越多,花在任務切換的時間就越多,CPU執行任務的效率就越低,所以,要最高效地利用CPU,計算密集

多執行緒之IO密集型和CPU密集型

CPU密集型(CPU-bound) CPU密集型也叫計算密集型,指的是系統的硬碟、記憶體效能相對CPU要好很多,此時,系統運作大部分的狀況是CPU Loading 100%,CPU要讀/寫I/O(硬碟/記憶體),I/O在很短的時間就可以完成,而CPU還有許多運算要處理,CPU Loading很高

IO密集型和cpu密集型的多執行緒總結

執行緒是否越多越好? 分析如下: 一個計算為主的程式(專業一點稱為CPU密集型程式)。多執行緒跑的時候,可以充分利用起所有的cpu核心,比如說4個核心的cpu,開4個執行緒的時候,可以同時跑4個執行緒的運算任務,此時是最大效率。 但是如果執行緒遠遠超出cpu核心數量 反而會使得任

java (x) 關於多執行緒的CPU密集型IO密集型這件事

CPU密集型 CPU密集型會消耗掉大量的CPU資源,例如需要大量的計算,視訊渲染啊,模擬啊之類的。這個時候CPU就卯足了勁在執行,這個時候切換執行緒,反而浪費了切換的時間,效率不高。 就像你的大腦是CPU,你本來就在一本心思地寫作業,多執行緒這時候就是要你寫會作業,然後立刻敲一會程式碼,然後在P個圖,然後

CPU密集型 VS IO密集型

函數 占用率 行高 運行 同時 性能 這樣的 可能 切換 CPU密集型 CPU密集型也叫計算密集型,指的是系統的硬盤、內存性能相對CPU要好很多,此時,系統運作大部分的狀況是CPU Loading 100%,CPU要讀/寫I/O(硬盤/內存),I/O在很短的時間就可以完成,

關於Python 多執行緒為何適合IO密集型任務

io密集型任務,一般情況下,io有傳送資料(output)和返回資料(input)兩個過程。就是傳送訊息,等待返回訊息。python多執行緒在處理io的時候,一個執行緒獲得GIL傳送訊息,然後等待返回訊息(阻塞),python此時釋放GIL, 其他執行緒得到GIL傳送訊息,然後同樣等待返回訊息(

python CPU密集型IO密集型 多程序更優於多執行緒 GIL

CPU密集型和IO密集型 最近在看Python的多執行緒,經常我們會聽到老手說:“python下多執行緒是雞肋,推薦使用多程序!”,但是為什麼這麼說呢? 要知其然,更要知其所以然。所以有了下面的深入研究: 首先強調背景: 1、GIL是什麼?GIL的全稱是Global I

什麼是CPU密集型IO密集型

CPU密集型(CPU-bound) CPU密集型也叫計算密集型,指的是系統的硬碟、記憶體效能相對CPU要好很多,此時,系統運作大部分的狀況是CPU Loading 100%,CPU要讀/寫I/O(硬碟/記憶體),I/O在很短的時間就可以完成,而CPU還有許多運

Java高併發程式設計——為IO密集型應用設計執行緒數與劃分任務

文章轉自:http://www.tuicool.com/articles/fA7rMn 實際工作中的三類程式適用於以併發的形式來提速: 1. 服務程式:同時響應多個使用者請求 2. 計算密集型程式:併發計算,將問題拆分為子任務、併發執行各子任務並最終將子任務的結果彙

IO密集型和CPU密集型

CPU密集型(CPU-bound)CPU密集型也叫計算密集型,指的是系統的硬碟、記憶體效能相對CPU要好很多,此時,系統運作大部分的狀況是CPU Loading 100%,CPU要讀/寫I/O(硬碟/記憶體),I/O在很短的時間就可以完成,而CPU還有許多運算要處理,CPU Loading很高。在多重程式系統

為什麼PHP不適合計算密集型業務

回答這個問題,我們來了解一下為什麼說PHP慢? PHP的慢是相對於C/C++級別的語言來說,事實上,PHP語言最初的設計,就不是用來解決計算密集型的應用場景。我們可以這樣粗略理解為,PHP為了提升開發效率,而犧牲了執行效率。 我們知道PHP一個很大的特點,就是弱型別特性,也就是說,我可以隨意定義一個變數,然

CPU-bound(計算密集型) 和 I/O bound(I/O密集型)

如果所有的任務都是計算(CPU)密集型的,則建立處理器可用核心數這麼多個執行緒就可以了,這樣已經充分利用了處理器,也就是讓它以最大火力不停進行計算。建立更多的執行緒對於程式效能反而是不利的,因為多個執行緒間頻繁進行上下文切換對於程式效能損耗較大。執行緒數=cpu核心數+1