閱讀149 返回首頁    go 阿裏雲 go 技術社區[雲棲]


深入理解並行編程-分割和同步設計(三)

設計準則

上麵的章節中給出了三個並行編程的目標:性能、生產率和通用性。但是還需要更詳細的設計準則來真正的指導真實世界中的設計,這就是本節將解決的任務。在真實世界中,這些準則經常在某種程度上衝突,這需要設計者小心的權衡得失。

這些準則可以被認為是設計中的阻力,對這些阻力進行恰當權衡,這就稱為“設計模式”[Ale79],[GHJV95]。

基於三個並行編程目標的設計準則是加速、競爭、開銷、讀寫比率和複雜性。

加速:性能增加是花費如此多時間和精力進行並行化的主要原因。加速的定義是運行程序的順序執行版本所需要的時間,比上執行並行版本所需時間的比例。

競爭:如果對於一個並行程序來說,增加更多的CPU並不能讓程序忙起來,那麼多出來的CPU是因為競爭的關係而無法有效工作。可能是鎖競爭、內存競爭或者其他什麼性能殺手的原因。

工作-同步比率:單處理器、單線程、不可搶占、不可中斷版本的並行程序完全不需要任何同步原語。因此,任何消耗 在這些原語上(通信中的cache miss、消息延遲、加解鎖原語、原子指令和內存屏障等)的時間都是對程序意圖完成的工作沒有直接幫助的開銷。重要的衡量準則是同步開銷與臨界區中代碼的 開銷之間的關係,更大的臨界區能容忍更大的同步開銷。工作-同步開銷比率與同步效率的概念有關。

讀-寫比率:極少更新的數據結構更多是複製而不是分割,並且用非對稱的同步原語來保護,以提高寫者同步開銷的代價來降低讀者的同步開銷。對頻繁更新的數據結構的優化也是可以的,詳見第4章的討論。

複雜性:並行程序比相同的順序執行程序複雜,這是因為並行程序要比順序執行程序維護更多狀態,雖然這些狀態在某些情況下(有規律並且結構化的)理解起來很容易。並行程序員必須考慮同步原語、消息傳遞、鎖的設計、臨界區識別以及死鎖等諸多問題。

更大的複雜性通常轉換成了更高的開發和維護代價。因此,代碼預算可以有效限製對現有程序修改的數目和類型,因為原有程序在一定程度的加速隻值這麼多 的時間和精力。進一步說,還有可能對順序執行程序進行一定程度的優化,這比並行化更廉價、更有效。並行化隻是眾多優化中的一種,並且隻是一種主要應用於 CPU是瓶頸的優化。

這些準則合在一起,讓程序達到了最大程度的加速。前三個準則相互交織在一起,所以本節剩下的部分將分析這三個準則的交互關係。

請注意,這些準則也是需求說明的一部份。必須,加速既是願望(“越快越好”),又是工作負荷的絕對需求,或者說是“運行環境”(“係統必須至少支持每秒1百萬次的web點擊”)。

理解這些設計準則之間的關係,對於權衡並行程序的各個設計目標十分有用。

1. 程序在臨界區上所花的時間越少,潛在的加速就越大。這是Amdahl定律的結果,這也是因為在一個時刻隻能隻有一個CPU進入臨界區的原因。

2. 程序在某個互斥的臨界區上所耗費的時間必須大大小於CPU數的倒數,因為這樣增加CPU數目才能達到事實上的加速。比如在10個CPU上運行的程序隻能在關鍵的臨界區上花費小於1/10的時間,這樣擴展性才好。

3. 競爭效應所浪費的多餘CPU和/或者本來該是加速的牆上時間,應該少於可用CPU的數目。CPU數和實際的加速之間的差距越大,CPU使用的效率越低。同樣,需要的效率越高,可以做到的加速就越小。

4. 如果可用的同步原語相較它們保護的臨界區來說開銷太大,那麼加速程序運行的最佳辦法是減少調用這些原語的次數(比如分批進入臨界區、數據所有權、RCU或者使用粒度更粗的設計——比如代碼鎖)。

5. 如果臨界區相較守護這塊臨界區的原語來說開銷太大,那麼加速程序運行的最佳辦法是增加程序的並行化程度,比如使用讀寫鎖、數據鎖、RCU或者數據所有權。

6. 如果臨界區相較守護這塊臨界區的原語來說開銷太大,並且被守護的數據結構讀多於寫,那麼加速程序運行的最佳辦法是增加程序的並行化程度,比如讀寫鎖或者RCU。

7. 各種增加SMP性能的改動,比如減少鎖競爭程度,能改善響應時間。


文章轉自 並發編程網-ifeve.com

最後更新:2017-05-22 15:33:36

  上一篇:go  windows對象屬性總結
  下一篇:go  JAVA性能優化調查結果(第二部分)