1. Amdahl定律編程
一個很簡單的量化公式,用來計算一個程序中串行部分所佔多少對程序加速比的影響或者用來計算計算機硬件配置中某個設備的速度提升可以將整個系統的速度提升多少。多線程
假設一個串行程序執行的總時間爲1,不能被並行化的部分佔的時間比例爲p,即串行化的部分爲p,可並行化的時間爲:1-p。若是用n個核用來加速的話,加速比爲:架構
若是一個程序中只有50%部分可以被並行化,那麼即便使用100個核,能達到的最好的加速比爲1.98,即不會達到2.除非n無窮大。併發
Amdahl就像克萊姆準則同樣不能用於實際中,由於很難精確的使用這個公式。咱們須要找到程序中全部的串行部分和並行部分。串行部分不單單存在於代碼中必需的依賴關係,可能還有底層庫函數中的串行,還有操做系統的串行部分,甚至還有硬件自己的串行部分。異步
2. 異步應用程序的實現方法函數
常見的實現方式有:多線程+同步,異步I/O,非阻塞I/O,信號,事件。異步I/O和非阻塞I/O並非一回事,固然在有些場合下也會混淆使用。通常來講,異步側重於表達並行,兩個執行流能夠同時進行。非阻塞通常還包含一個查詢的過程,由於要查詢所要進行的操做是否完成。優化
異步I/O使用起來難度比多線程大,理解和維護起來的難度通常也比多線程麻煩。一樣使用信號也是這個缺點,由於單個線程可使用同步的方式,線程之間可使用信號來通訊。這樣就好像一我的同時作不少件事情和一個團隊來協做來完成這些事情的區別同樣。後者的執行邏輯會更加清晰,並且多線程+同步的方式可以實現全部異步I/O帶來的優點。操作系統
使用UNIX信號的方式有嚴重的侷限性,由於收到信號後全部的邏輯放在一個信號處理函數中執行,這並非信號處理函數設計的初衷。並且,使用信號會顯得程序的組織結構比較混亂,維護起來比較麻煩。.net
事件流也是實現異步應用程序的一種方式。通常系統底層會將應用程序收到的各類事件緩衝到一個隊列中,而後又底層負責將各類事件對應到一個回調函數上,串行的處理各個事件,即調用各個回調函數。這種方式的最大缺點就是有些事件的回調函數的執行事件比較長,會致使其餘事件不能獲得很好地相應。在Windows系統的.NET架構上,事件+回調函數是使用的比較多的一種方式。事件流的缺點在於其處理的順序性。固然事件流+回調函數+多線程是一種不錯的選擇。
3. 編程模型
各個編程模型的計算能力是等價的,可是對問題抽象層次是不一樣的。彙編語言在表示程序的結構方面顯得比較笨拙,可是使用C語言就將程序的設計結構顯式的表現出來了。使用C語言進行數據封裝和多態處理顯得很笨拙,使用C++就能很好地處理這個問題。使用關係數據庫在解決大規模數據問題上顯得很笨拙,使用Map-Reduce就能很好的處理某些問題。非線程代碼不能顯式的表達操做的同步性,使用線程代碼就能很好的表達出這些同步性。線程源代碼讓獨立的模塊或者鬆耦合的模塊更加清楚的表現出來。
不一樣的編程模型對應着不一樣的抽象層次,對於問題域的抽象恰到好處的抽象模型有助於咱們解決更復雜的問題。
4. 什麼狀況下使用線程
使用線程是有代價的,若是程序是計算密集型且每一步都有依賴,那麼使用線程反而會致使效率降低,由於多個線程之間須要切換,還要負責維護鎖,信號量等設施。對於可並行的計算密集型問題和I/O與計算可重疊的問題使用多線程通常會達到顯著的效果。程序中有多個可併發的模塊的時候,使用線程也能提升程序的響應速度。
如需更全面地瞭解編譯器優化,請參閱優化注意事項:http://software.intel.com/zh-cn/articles/optimization-notice#opt-cn