轉自:http://www.cnblogs.com/wasd/archive/2009/04/07/1430859.htmlphp
並行計算簡介html
做者: Blaise Barney, 勞倫斯利弗莫爾國家實驗室程序員
譯者:盧洋,同濟大學,2009年4月算法
原文地址:https://computing.llnl.gov/tutorials/parallel_comp/數據庫
目錄編程
1 摘要數組
2 概述緩存
2.1 什麼是並行計算安全
2.2 爲何使用並行計算服務器
3 概念和術語
3.1 馮諾依曼體系結構
3.2 Flynn經典分類法
3.3 一些通用的並行術語
4 並行計算機存儲結構
4.1 共享內存
4.2 分佈式內存
4.3 混合型分佈式共享內存
5 並行編程模型
5.1 概覽
5.2 共享內存模型
5.3 線程模型
5.4 消息傳遞模型
5.5 數據並行模型
5.6 其餘模型
6 設計並行程序
6.1 自動化 vs. 手工並行化
6.2 問題的理解和程序
6.3 問題分解
6.4 通訊
6.5 同步
6.6 數據依賴
6.7 負載平衡
6.8 粒度
6.9 I/O
6.10 並行程序設計的限制和消耗
6.11 性能分析與調整
7 並行示例
7.1 數組程序
7.2 PI 的計算
7.3 簡單的加熱等式
7.4 一維的波等式
8 參考和更多信息
爲了讓新手更加容易熟悉此話題,本教程覆蓋了並行計算中比較基礎的部分。首先在概述中介紹的是與並行計算相關的術語和概念。而後探索並行存儲模型和編程模型這兩個話題。以後討論一些並行程序設計相關的問題。本教程還包含了幾個將簡單串行化程序並行化的例子。無基礎亦可閱讀。
l 傳統上,通常的軟件設計都是串行式計算:
² 軟件在一臺只有一個CPU的電腦上運行;
² 問題被分解成離散的指令序列;
² 指令被一條接一條的執行;
² 在任什麼時候間CPU上最多隻有一條指令在運行
l 在最簡單的情形下,並行計算是使用多個計算資源去解決可計算問題。
² 用多核CPU來運行;
² 問題被分解成離散的部分能夠被同時解決;
² 每一部分被細分紅一系列指令;
² 每一部分的指令能夠在不一樣的CPU上同時的執行;
l 計算資源能夠包括:
² 多核CPU;
² 任意數量的CPU用網絡鏈接起來;
² 或者以上二者結合;
l 可計算問題一般展現出以下的特性:
² 能分解成能夠同時解決的離散的工做塊;
² 同一時刻能夠執行多條程序指令;
² 一般用多個計算資源解決問題所花的時間要比單個計算資源要短;
Ø 宇宙是並行的
l 並行計算是由串行計算髮展而來,試圖去模仿真實世界中事物的處理過程:許多複雜的互相關聯的事件同時發生,例如:
銀河系的變換; 行星的運動; 天氣和海洋的變化;
交通堵塞; 大陸板塊遷移; 炊煙升起;
自動的流水線; 建造空間飛行器; 開車買漢堡;
Ø 並行計算的用途:
l 在歷史上,並行計算被認爲是高端計算,並用於爲複雜的科學計算和基於真實世界的工程問題建模。下面是一些例子:
² 大氣層、地球、環境
² 物理學應用、核能、原子能、凝聚態、高壓、溶解、光電子;
² 生物科學、生物工程、基因學
² 化學、分子科學
² 地理和地震學
² 機械工程、從彌補術到空間飛行器
² 電氣工程、電路設計、微電子學
² 計算機科學、數學
l 今天,商務應用是推進快速計算機發展的更大的推進力。這些應用須要用複雜的方法處理大量數據。例如:
² 數據庫、數據挖掘
² 石油勘探
² 網絡搜索引擎、基於網絡的商務服務
² 醫學成像和診斷
² 製藥設計
² 國有企業或跨國企業的管理
² 金融經濟建模
² 高級製圖和虛擬現實、特別實在娛樂事業上
² 網絡視頻和多媒體技術
² 協同工做環境
Ø 主要的緣由有:
l 節省時間和成本:理論上,使用更多的資源會使一個任務提早完成,並且會節約潛在的成本。何況可使用便宜的、甚至市面將要淘汰的CPU來構建並行聚簇。
l 解決更大規模的問題:不少問題是至關龐大而複雜的,尤爲是當計算機的內存受到限制的時候,用單個計算機來解決是不切實際或者根本不可能的。例如:
² "Grand Challenge" (en.wikipedia.org/wiki/Grand_Challenge) 問題須要Peta級浮點運算能力和存儲空間的計算資源。
² 網絡搜索引擎和網絡數據庫每秒鐘要執行上百萬次的處理。
l 支持並行:單一的計算資源在同一時刻只能作一件事情。多個計算資源可以同時作不少事情。例如:Access Grid (http://www.accessgrid.org/)提供一個全球的合做網絡,在這裏來自世界上不一樣國家的人們能夠開會並「現場」指導工做。
l 使用非本地資源: 當缺乏本地計算資源的時候可使用普遍的網絡或Internet計算資源。例如:
² SETI@home (setiathome.berkeley.edu) 使用超過330000個計算機來執行每秒超過528T次浮點運算;(August 04, 2008)
² Folding@home (folding.stanford.edu)使用超過340,000 計算機來執行每秒4.2P次浮點運算 (November 4, 2008)
l 串行計算的限制:在理論上和實際上,想要輕易地製造更快的串行計算機存在着巨大的限制。
² 傳輸速度——線性計算機的執行速度直接取決於數據在硬件中傳輸的速度。光速的絕對限制是每納秒30cm,銅導線是每納秒9cm。不斷提高的執行速度更加靠近極限。
² 微型化的極限——處理器技術使芯片集成了更多的晶體管。可是,即便使用分子或者原子級別的組件也會很快達到芯片集成晶體管的極限。
² 經濟上的限制——讓單個芯片變得更快須要增長昂貴的投入。用多個通常的芯片來取代單個高性能的芯片或許性能會更好並且更便宜。
如今的計算機體系結構愈來愈依賴於硬件層次的並行來提升性能:
² 多個執行單元
² 管道指令
² 多核
Ø 誰?什麼?
l Top500.org 給出了並行計算用戶的數據統計——下面的圖標只是一個樣例。下面幾點須要注意:
² 扇形可能重疊——例如,研究的部分可能在經典研究中。做者不得不二選一。
² 目前爲止未分類的最大應用多是多種應用集合。
Ø 將來
在過去的20年裏,更快速網絡、分佈式系統、多核處理器體系結構(甚至是在桌面應用級別)的發展趨勢已經很清楚的指出並行化是將來科學計算的發展方向。
以匈牙利數學家約翰. 馮諾依曼命名,他是第一個在1945年的論文中提出通用電子計算機必要條件的創始人。
從那時開始,實際上全部的計算機都聽從這個基本的設計,區別於早期的硬佈線編程的計算機設計。
主要有五個主要的部件構成:內存、控制單元、邏輯計算單元、輸入輸出
讀/寫,隨機存儲內存用於儲存程序指令和數據:程序指令是告訴計算機作什麼事的代碼數據、數據是程序用到的簡單數據。
控制單元從內存中取回指令/數據,解碼指令而後連續協調操做來完成編碼工做。
計算單元完成基本的計算操做。
輸入輸出是用戶操做的界面。
有不少方法給並行計算機分類,其中,Flynn分類法從1966年開始使用被你們廣爲接受。
Flynn分類是利用兩個獨立的標準指令和數據對多核計算機體系結構進行劃分的。每個標準有兩種可能的值:單個或者多個
下面的矩陣定義了4中可能的Flynn分類
S I S D 單指令單數據 |
S I M D 單指令多數據 |
M I S D 多指令單數據 |
M I M D 多指令多數據 |
Ø 單指令單數據(SISD)
串行計算機
單個指令:在一個系統時鐘週期只有一條指令能夠被執行。
單數據:在一個系統時鐘週期只有一個數據流能夠被用來輸入。
肯定性執行。
這是迄今爲止最老的,但大多數通用計算機都是這個類型。
例如:老一代的大型機、微機和工做站,還有如今大多數的PC機。
UNIVAC1 | IBM 360 | CRAY1 |
CDC 7600 | PDP1 | Dell Laptop |
Ø
單指令多數據:
並行計算機的一種
單指令:全部的處理單元在給定的時鐘週期只能
執行相同的指令。
多數據:每個處理器單元能夠同時處理不一樣的
數據元素。
最適合處理高度規則的問題,如圖形圖像處理。
同步,肯定性執行。
兩類:處理器數組和向量流水線。
例如:處理器矩陣:Connection Machine CM-2,
MasPar MP-1 & MP-2, ILLIAC IV;向量流水線:IBM 9000, Cray X-MP, Y-MP & C90, Fujitsu VP, NEC SX-2, Hitachi S820, ETA10。
最早進的計算機,特別是帶有圖形處理器單元的計算機都使用SIMD指令集和執行單元。
ILLIAC IV | MasPar |
Cray X-MP | Cray Y-MP | Thinking Machines CM-2 | Cell Processor (GPU) |
Ø 多指令單數據(MISD):
單數據流進入多處理器單元。
每個處理器單元經過獨立的指令流在獨立的操做數據。
這種計算機幾乎在市面上找不到。有一個實驗機Carnegie-Mellon C.mmp
可能用於單信號流上多頻率過濾、用多密碼學算法破解單碼信息。
Ø 多指令多數據(MIMD)
如今,大多數通用並行計算機都是這種。
多指令:每一個處理器能夠執行不一樣的指令流
多數據:每一個處理器能夠用不一樣的數據流。
同步或異步、肯定性或非肯定性執行。
例如:大多數的超級計算機、網格計算機、多核SMP計算機,多核PC機。
注意:不少MIMD體系結構也包含SIMD執行子構件。
像其餘的東西同樣,並行計算機有他本身的術語。下面列出了一些與並行計算相關的通用的術語。其中大多數都會在後面再進行詳細的討論。
Task:可計算工做在邏輯上不連續的分區。一個任務一般是一個程序或者相似程序同樣的能夠被處理器執行的指令集。
Parallel Task:一個任務能夠被多個處理器安全的並行的執行,產生正確的結果。
Serial Execution:程序相繼的執行,每次一個狀態。在最簡單的狀況下,單核處理器就是這樣運行的。但是,實際上全部並行的任務有一些並行程序的區域必定要串行的執行。
Parallel Execution:一個或多個任務同時執行的程序,每一個任務同時可以執行相同的或不一樣的代碼語句。
Pipelining:不一樣的處理器單元把一個任務根據輸入流來分解成一系列步驟來執行,至關於一條流水線;並行計算的一種。
Shared Memory(共享內存):徹底從硬件的視角來描述計算機體系結構,全部的處理器直接存取通用的物理內存(基於總線結構)。在編程的角度上來看,他指出從並行任務看內存是一樣的視圖,而且可以直接定位存取相同的邏輯內存位置上的內容,無論物理內存是否真的存在。
Symmetric Multi-Processor(對稱多處理器):這種硬件體系結構是多處理器共享一個地址空間訪問全部資源的模型;共享內存計算。
Distributed Memory(分佈式存儲):從硬件的角度來看,基於網絡存儲的物理內存訪問是不常見的。在程序模型中,任務只能看到本地機器的內存,當任務執行時必定要用通訊才能訪問其餘機器上的內存空間。
Communication:並行任務都須要交換數據。有幾種方法能夠完成,例如:共享內存總線、網絡傳輸,然而無論用什麼方法,真實的數據交換事件一般與通訊相關。
Synchronization:實時並行任務的調度一般與通訊相關。老是經過創建一個程序內的同步點來完成,一個任務在這個程序點上等待,直到另外一個任務到達相同的邏輯設備點是才能繼續執行。同步至少要等待一個任務,導致並行程序的執行時間增長。
Granularity(粒度):在並行計算中,粒度是定量化的用來測定通訊和計算比率的方法。粗糙級:在兩個通訊事件之間能夠完成相對大量的可計算工做。精細級:在兩個通訊事件之間只能完成相對較少許的可計算工做。
Observed Speedup:測量代碼並行化以後的加速比。這是最簡單也最普遍使用的測量並行程序性能的方法。
wall-clock time of serial execution ———————————————————— wall-clock time of parallel execution |
Parallel Overhead(並行開銷):對並行任務調度花費的時間沒有作有用的工做。並行開銷能夠包含以下因素:任務啓動時間、同步、數據通訊、並行編譯器、庫、工具、操做系統等花費的軟件開銷,任務終止的時間等。
Massively Parallel(大規模並行):指包含給定的並行系統硬件——有多個處理器。「多個「的意思是能夠不斷的增長,可是目前大規模並行計算機由上百個處理器構成。
Embarrassingly Parallel:同時解決不少類似的獨立的任務;任務之間基本不須要調度。
Scalability:指的是並行系統經過增長更多的處理器的個數按比例提升並行性能的能力。促進可擴展性的因素有:硬件——特別是內存、CPU帶寬和網絡通訊,應用程序算法,相關的並行開銷、特定的應用和編碼方式的特徵。
Multi-core Processors:一個CPU上有多個處理器。
Cluster Computing:用通常的處理器單元(處理器、網絡、SMP)來構建並行系統。
Supercomputing / High Performance Computing(高性能計算):使用世界上最快最大的機器來解決大規模的問題。
4 並行計算機存儲結構
Ø 通常特性:
共享內存計算機有不少種類,可是都有一個共同的特色,全部的處理器都把內存做爲全局的地址空間來進行訪問。
多處理器可以單獨的運行,可是都共享相同的內存地址。
一個處理器對內存的修改對其餘的處理器是可見的。
共享內存的機器能夠根據內存的存取次數大致分紅兩類:UMA和NUMA。
Ø UMA統一的內存訪問
如今大多數的SMP處理器就屬於此類。
同核處理器。
對內存的存儲機會和次數均等。
緩存連貫意思是若是一個處理器更新共享內存,
其餘的全部處理器都會知道。這是由硬件層來實現的。
Ø NUMA非統一的內存訪問
一般是在物理層上連接兩個或多個SMP構成的。
一個SMP可以直接訪問另外一個SMP的內存
不是全部的處理器都有對內存平等的訪問機會
經過鏈接的內存訪問會更慢
如能夠保持緩存的連貫性,也能夠叫作CC-NUMA - Cache Coherent NUMA。
Ø 優勢:
全局的地址空間提供了一個對用戶友好的編程視角。
因爲內存CPU之間的密切合做使得任務間的數據共享即快速又統一。
Ø 缺點:
主要的缺點是內存和CPU之間的可擴展性較差。增長CPU以後會增長共享內存和CPU之間傳輸時間,在緩存連貫的系統中,也會增長與緩存內存管理相關的數據流量。
程序員有責任同步系統以確保正確的訪問全局存儲空間。
代價:用更多的處理器設計和生產共享內存機器愈來愈困難並且愈來愈昂貴。
Shared Memory (UMA)
Shared Memory (NUMA)
Ø 通常特徵:
像共享內存系統同樣,分佈式內存系統也有不少種,可是有一個共同特色:分佈式存儲系統須要通訊網絡來鏈接核間內存。
處理器都有各自的內部寄存器。一個核內的存儲地址對其餘核不可見,對於全部CPU都沒有全局地址空間的概念。
因爲每一個處理器都有本身獨立的內存,本地內存的改變將不會影響到其餘的處理器。所以沒有實現緩存一致性。
當一個處理器須要訪問另外一個處理器的數據時,程序員的任務就是清楚的定義何時用什麼方法來通訊。任務間的同步問題也是程序員的職責。
總線網絡通訊的方式有不少種,最簡單的方法相似以太網。
Ø 優勢:
a) 內存能夠和CPU的個數一塊兒擴展。增長處理器的個數將使得內存的大小等比例增長。
b) 每一個處理器能夠沒有衝突的快速訪問本身的內存,也不需維護緩存一致性的開銷。
c) 成本效益:能夠用通常的下市的CPU加上網絡來構建。
Ø 缺點:
d) 1程序員將要負責全部處理器間數據通訊相關的細節問題。
e) 2很難從基於全局內存空間的數據結構上創建起到分佈式內存管理的映射。
f) 3非統一的內存訪問次數。
a) 當今最快最大計算機就是這種混合行分佈式共享內存體系結構。
b) 共享內存組件一般用於緩存一致的SMP機器。在特定的SMP核上能夠尋址機器的全局內存。
c) 分佈式內存組件是由多個SMP網絡構成。SMP只能看到本身的緩存區。所以SMP間須要通訊。
d) 如今的趨勢顯示這種類型的存儲體系結構將會在不遠的未來在高端計算機上繼續流行和發展。
e) 優勢和缺點:同上。
如今主要如下幾種通用的並行編程模型:共享內存、線程、消息傳遞、數據並行、混合模型。
並行編程模型是在硬件和內存體系結構層之上的抽象概念。
仔細研究能夠發現,這些模型並非爲了某一個特定的機器或內存體系結構而設計的。事實上,這些模型均可以在硬件層之下實現。兩個例子:
Ø 分佈式內存機器上的共享內存模型:Kendall Square Research (KSR) ALLCACHE approach。機器的內存物理上的實現是分佈式內存,可是對用戶來講是一個單一的全局地址空間。通常來講,這種方法叫作虛擬共享內存。注意:儘管KSR再也不應用於商務貿易方面,可是不表明其餘的供應商之後不會再利用這種方式。
Ø 共享內存機器上的消息傳遞模型:MPI on SGI Origin。SGI Origin 使用 CC-NUMA類型的共享內存體系結構,這種體系結構可使得每一個任務均可以直接訪問全局內存。然而,MPI發送和接受消息的功能,就像一般在網絡上實現的分佈式內存機器同樣,實現方法類似,還十分通用。
要使用哪一個模型一般取決於能夠得到哪一個模型和我的的選擇。儘管如今有模型相對於其餘的來講確實有更好的實現方法,可是這裏沒有「最好」的模型。
接下來將詳細描述上面提到的每一個模型,也會討論它們的實現方法。
a) 在共享編程模型中,任務間共享統一的能夠異步讀寫的地址空間。
b) 共享內存的訪問控制機制可能使用鎖或信號量。
c) 這個模型的優勢是對於程序員來講數據沒有身份的區分,不須要特別清楚任務簡單數據通訊。程序開發也相應的得以簡化。
d) 在性能上有個很突出的缺點是很難理解和管理數據的本地性問題。
n 處理器本身的緩衝區中使用數據,使用完畢後刷新緩存寫入內存,此時可能發生多個處理器使用相同數據的總線衝突。
n 不幸的是,通常用戶很難理解或控制數據的本地化問題。
Ø 實現
在共享內存平臺上,本地的編譯器將會把用戶程序變量轉換到全局地址空間中。
如今市面上尚未通常的分佈式內存平臺的實現。然而,先前在咱們概覽部分提到的KSR,它就是在分佈式的機器上提供了一個共享的數據平臺。
Ø 在並行編程的線程模型中,單個處理器能夠有多個並行的執行路徑。
Ø 線程模型的構成以下:
l 操做系統調度主程序a.out開始運行,a.out加載全部必要的系統資源和用戶資源開始執行。
l a.out完成一些串行工做,而後建立一些能夠被操做系統調度的並行任務(線程)去執行。
l 每次線程都有本身的數據,並且共享整個a.out的資源。這樣就節省了拷貝程序資源給每一個線程的開銷。這樣線程之間能夠並行執行子程序。
l 線程之間經過全局內存進行通訊。這個須要同步構造來確保多個線程不會同時更新同一塊全局內存。
l 線程執行完了就自動銷燬,可是主程序a.out在應用程序完成以前一直存在,維護必要的共享資源。
Ø 線程一般和共享內存體系結構和操做系統相關。
u 實現:
ü 從程序的角度出發,線程的實現一般包括:
1)並行代碼須要調用的子程序庫;
2)串行或者並行源代碼中的一套編譯器指令。
ü 在以上兩部分中,程序員都要負責制定全部的並行機制。
ü 線程的實現並非什麼新技術,硬件供應商已經實現了他們本身的線程版本。線程的實現機制本質上的不一樣使得程序員很難開發出能夠移植的多線程應用程序。
ü 不一樣的標準產生了兩個不一樣的線程實現方式:POSIX線程和OpenMP
u POSIX線程:
ü 基於庫函數的,須要並行編碼。
ü IEEE POSIX 1003.1c 中有具體描述。
ü 只適用於C語言
ü 一般是指Pthreads
ü 大多數的硬件供應商如今爲本身的線程實現加入Pthreads
ü 十分清晰的並行,須要程序員特別關注實現的細節。
u OpenMP:
ü 基於編譯器指令,可使用串行代碼。
ü 有一羣計算機軟硬件廠商共同定義並支持。OpenMP在1997年完成Fortran的API,於1998年完成C/C++的API
ü 簡潔並且跨平臺(Unix、Windows NT)
ü 有C/C++和Fortran的實現
ü 使用簡單,支持增量並行
微軟有本身一套獨立的線程實現機制,與以上二者都不相關。
u 更多信息
POSIX的教程computing.llnl.gov/tutorials/pthreads
OpenMP的教程computing.llnl.gov/tutorials/openMP
消息傳遞模型有如下三個特徵:
1) 計算時任務集能夠用他們本身的內存。多任務能夠在相同的物理處理器上,同時能夠訪問任意數量的處理器。
2) 任務之間經過接收和發送消息來進行數據通訊。
3) 數據傳輸一般須要每一個處理器協調操做來完成。例如,發送操做有一個接受操做來配合。
Ø 實現
從編程的角度上來看,消息傳遞的實現一般由源代碼中的子程序庫構成。程序員負責決定全部的並行機制。
1980年以來出現了大量的消息傳遞機制的庫函數。這些實現本質上是不一樣的,這就加大了程序員開發可移植的應用程序的難度。
1992年,創建了MPI討論組,他們的首要目標就是創建消息傳遞實現的標準接口。
消息傳遞接口(MPI)的第一部分於1994年完成,第二部分完成於1996年。兩部分MPI規範均可以在這裏下載http://www-unix.mcs.anl.gov/mpi/。
MPI如今已經成爲了工業界消息傳遞的標準了,而且代替了市面上幾乎全部的其餘的實現方法。大多數比較流行的並行計算機都至少實現MPI的一個標準,有些還徹底知足標準2。
對於共享內存體系結構,MPI的實現一般不使用網絡來進行任務間的通訊。替代的辦法是利用共享內存來進行通訊,這樣能夠提升性能。
Ø 更多信息:
MPI的教程computing.llnl.gov/tutorials/mpi;
l 數據並行模型有如下特性:
並行工做主要是操縱數據集。數據集通常都是像數組同樣典型的通用的數據結構。
任務集都使用相同的數據結構,可是,每一個任務都有本身的數據。
每一個任務的工做都是相同的,例如,給每一個數組元素加4。
l 在共享內存體系結構上,全部的任務都是在全局存儲空間中訪問數據。在分佈式存儲體系結構上數據都是從任務的本地存儲空間中分離出來的。
實現
l 使用數據並行模型編程一般都是用構造並行的數據來寫程序。構造方法是調用並行數據的子函數庫,而後數據並行編譯器就能夠識別構造時用到的編譯器指令。
l Fortran90和95:ISO/ANSI標準擴展於Fortran77:
包含Fortran77中的全部東西;加入新的代碼格式;添加新的特性集;增長程序結構和命令;增長函數、參數等變量;添加數組處理;增長新的遞歸函數和內部函數;和不少其餘的新特性。大多數通用的並行平臺均可以使用。
l 編譯器指令:可讓程序員指定數據的排列和分佈。針對大多數的通用並行平臺都有Fortran的實現。
l 分佈式內存模型的實現是用編譯器將程序轉換成標準的代碼,這些代碼經過調用MPI庫函數來將數據分配給全部的進程。全部的消息傳遞對於程序員來講是不可見的。
上面提到的並行編程模型都是已經存在,並且會隨着計算機軟硬件的發展繼續進化。除了這些以外這裏還有三個更爲通用的模型。
Ø 混合型:
這個模型中,是由兩個或多個模型組合在一塊兒實現的。
當前通用的混合模型的例子就是:由消息傳遞模型(MPI)和線程模型(POSIX)或者共享內存模型(OpenMP)組成而成。
混合模型中其餘比較通用的模型是:將數據並行和消息傳遞組成起來。正如咱們上面在數據並行模型部分提到的那樣,在分佈式體系結構上實現數據並行模型其實是用消息傳遞的方法來爲任務間傳遞數據的,對程序員是透明的。
Ø 單程序多數據型(SPMD):
SPMD其實是一個高層次的編程模型,是在前面提到的並行編程模型基礎之上構建的。
一段程序能夠被全部的任務同時的執行。
任務能夠同時執行同一個程序中的相同或不一樣指令。
SPMD程序一般都包含必要的邏輯,使得任務能夠有條件的或者分叉的執行那些能夠被執行的程序。因此任務沒有必要去執行整個程序,極可能只執行一小塊程序就能夠了。
全部的任務可能使用不一樣的數據。
Ø 多程序多數據型(MPMD):
與SPMD相似,MPMD也是高層次編程模型,創建在上面提到的並行編程模型之上。
MPMD應用程序多個執行程序。當程序並行執行時,每一個任務能夠執行相同或不一樣的程序做爲本身的工做。全部的程序可能使用不一樣的數據。
設計和開發並行程序是典型的人爲設計的過程。程序員負責識別並行性和實現並行機制。
一般,手工開發並行代碼是一件費時、複雜、容易出錯和迭代的過程。
這些年以來,開發出多種工具幫助程序員吧串行的程序轉換成並行的程序。最通用的工具類型是並行化編譯器或預編譯器,它們能夠自動把串行化程序並行化。
並行化編譯器一般有如下兩種工做方式:
1:全自動化
A)編譯器分析源代碼並識別代碼中的並行性。
B) 分析包括識別並行約束,計算使用並行機制所須要的代價,判斷是否是真的提升了性能。
C) 循環程序(do,for)是主要的自動並行化對象。
2:程序員直接指定並行化
A) 使用編譯器指令或者編譯器標記,程序員清楚的告訴編譯器如何來並行化代碼。
B) 也可能在程序中的一部分使用自動並行化。
若是你如今手中有串行的代碼須要並行化,並且時間和預算有限的狀況下自動並行化多是更好的選擇。可是在實施自動並行化以前這裏有些很重要的警告應該事先告訴你。
A) 可能產生錯誤的結果
B) 性能可能反而降低
C) 人爲編程的並行性靈活性更好
D) 只能用於代碼的子程序(主要是循環)
E) 分析可能指出程序有依賴或者代碼過於複雜而不能並行化。
本章剩餘的部分主要講解人爲開發並行代碼。
毫無疑問,開發並行軟件的第一步就是理解要並行處理的問題。若是寫好了串行化代碼,也有必要理解寫好的這份代碼。
在開始花時間嘗試開發問題的並行解決方案以前,首先應該判斷當前的問題是否真的能夠被並行。
可並行化例子:爲幾千個獨立的模塊構造方法計算潛在所需開銷,完成後找到花費最少的構造方法。這個例子能夠被並行處理。每一個模塊的構造方法是彼此獨立的。最小花費的計算也是可並行的問題。
不可並行化的例子:計算費伯那其Fibonacci數列(1,1,2,35,8,13,21……)F(K+2)=F(K+1)+F(K).這個問題不能夠並行化,覺得費伯那其數列的計算中每一項都依賴與其餘項,而不是獨立的。K+2這個計算用到了K和K+1的結果。三個子句不能夠獨立的計算,所以不能夠並行。
識別程序中的關鍵點:
A) 瞭解程序中哪裏作了大部分工做。大多數的科學和技術程序一般在某些地方完成了大部分的任務。
B) 性能分析工具在這裏頗有用。
C) 關注程序中關鍵點的並行,忽視那些只使用不多CPU利用率的部分程序。
識別程序中的瓶頸:
A) 是否存在特別慢或者致使可並行的工做中止或延誤的程序段?例如:I/O常常是系統瓶頸。
B) 有可能經過重構或者使用不一樣的算法能夠減小或消除程序中的瓶頸。
識別程序的限制因素。常見的限制是數據依賴,像Fibonacci數列中的那樣。
研究其餘可能的算法,這多是用來設計並行應用程序最重要的方法。
設計並行程序的第一步是將問題分解成離散的能夠被分配到多任務中的工做塊。這就是任務分解。
分解並行任務中的可計算工做的兩個基本方式是:做用域分解和功能分解。
1)做用域分解:
在這個方法中,與問題相關的數據將會被分解。每一個並行的任務只能使用部分數據。
有不一樣的方法能夠分解數據:
2)功能分解:
在這種方式中,主要關注要被完成的計算而不是操做數據的計算。問題是根據當前必定要完成的任務劃分的。每一個任務完成所有工做的一部分。
功能分解將問題很好的分解到不一樣的任務中去,例如:
A)生態系統模型
每一個程序都要計算給定羣體的總數目,每一個羣體的增加依賴它的鄰居。隨着時間的流逝,每一個進程計算它本身的狀態,而後和鄰居交換總數信息。全部的進程在下個時間節點再從新計算本身的狀態。
B)信號處理
音頻信號數據集是經過四個不一樣的可計算濾波器傳遞的。每一個濾波器都有本身獨立的進程。第一部分數據必定是先經過第一個濾波器傳輸。完成後,第二部分數據再經過第一個濾波器。第四部分數據經過了第一個濾波器後四個任務都開始運行。
C)氣候模型
模型中的每一個組件均可以看成一個獨立的任務。箭頭表明計算過程當中組件間的數據交換方向:大氣層模塊生成風速數據發送給大洋模塊,大洋模塊生產海洋水錶溫度發送給大氣層模塊使用,如此往復。
一般聯合使用以上兩種問題分解方法。
Ø 誰須要通訊?
任務之間是否須要通訊取決於您要解決的問題。
l 不須要通訊的狀況:
1)實際上有些類型的問題能夠將問題分解,並行執行時並不須要任務間共享數據。例如:假設一個圖像處理的程序在處理的圖像只有黑色,黑色的像素都反轉成黑色。圖像數據很容易就能夠被分解到多個任務上,這些任務顯然能夠獨立執行完成本身的那部分工做。
2)這種類型的問題稱爲「令人尷尬的並行計算」,由於他們不是直截了當的並行程序。任務之間仍是須要少量的通訊。
l 須要通訊的狀況:
大多數並行應用程序沒有這麼簡單,任務間須要彼此共享數據。例如,3D的熱擴散問題,其中一個任務的溫度計算要知道他周圍的任務的計算數據。周圍數據改變將直接影響此任務的數據。
Ø 值得考慮的因素:
設計任務間通訊的程序時須要考慮不少十分重要的因素。
1. 通訊開銷:
任務間通訊確定是須要開銷的。
本來用於計算的機器時鐘週期和計算資源將被用於給數據打包並傳輸。
頻繁的任務間通訊須要同步方法,同步使任務把時間花費在等待上而沒有工做。
通訊傳輸的競爭可能會佔用大量的帶寬,甚至影響性能。
2. 帶寬和延遲
延遲是從A點到B點發送數據須要花費的時間。一般是微秒級。
帶寬是每一個時間單元須要通訊的數據量。一般是Mb/s或者Gb/s級別。
若是發送不少小消息的話,延遲可能會佔用絕大多數的通訊資源。將小消息打包成大消息一次性傳遞一般更加高效,也會增長有效通訊帶寬。
3. 通訊的可見性
在消息傳遞模型中,通訊過程是很是清楚的,對程序員是可見的、能夠控制的。
在數據並行模型中,程序員不能確切的知道任務間的通訊是如何實現的,特別是在分佈式內存體系結構中。
4. 同步通訊和異步通訊
同步通訊須要某種類型的共享數據任務間的「握手」協議。程序員能夠將此過程很清楚的在程序中完成。
同步通訊一般是指一項任務完成後等待與他要通訊的任務,後者完成計算後才能夠進行通訊。
異步通訊容許程序之間能夠獨立的傳輸數據。例如:1號任務能夠在準備好後發送消息給2號任務而後當即作其餘的工做,2號任務接收數據到的時間不是特別重要。
異步通訊一般是指不阻塞的通訊,由於任務能夠一邊通訊一邊作其餘任務。
異步通訊最適合用於交叉計算問題。
5. 通訊的範圍
在設計並行代碼階段,知道哪一個任務須要彼此通訊是相當重要的。下面兩個描述的範圍能夠設計成同步的也能夠設計成異步的。
點到點:這裏包括兩個任務,一個做爲數據的製造者/發送者,另外一個做爲接收者/讀數據者。
彙集:這裏包括多個任務的數據共享問題,每一個任務都是組中的成員。
6. 通訊效率
程序員一般會根據影響通訊性能的因素進行選擇。這裏因爲篇幅限制只能提到一部分。
應該使用哪一種那個給定的模型?用消息傳遞模型爲例,只有MPI實如今給定的硬件平臺上可能比別的實現方法要快。
應該使用哪一種通訊操做?正如前面提到的,異步通訊操做可以提高程序的總體性能。
網絡媒體:有些平臺可能會提供多個網絡來進行通訊,那麼問題是那個網絡是最好的呢?
7. 開銷和複雜性
最後,請注意這裏提到的只是程序員要考慮的問題的一部分。
l 障礙
·一般障礙會影響全部的任務
·每一個任務完成本身的任務以後到達障礙區等待。
·當全部的任務都到達障礙點後全部的任務進行同步。
·執行到這裏有不一樣的狀況,一般須要作一串工做。其餘的狀況自動釋聽任務繼續完成別的工做。
l 鎖和信號量
·可能包括任意數量的任務。
·這種方法能夠串行訪問全局數據和代碼段。同時只能夠有一個任務使用鎖變量或者信號量。
·第一個訪問臨界資源的任務設置鎖,而後就能夠安全的訪問裏面被保護的數據或代碼。
·其餘的任務試圖操做臨界區,可是發現已經上鎖只能等到鎖的擁有者釋放鎖才能夠操做。
·阻塞和非阻塞兩種方式
l 同步通訊操做
·只涉及到執行通訊操做的任務。
·當一個任務完成通訊操做,須要某種調度方法來調度其餘參與通訊的任務。例如:當一個任務完成發送數據的操做他必須等待接受任務的確認信息,才能夠說明發送成功。
·其他的在前面通訊部分討論過。
Ø 定義:
·當程序的執行順序影響程序的執行結果時,咱們說程序間存在依賴。
·不一樣任務同時使用相同地址的存儲空間中的數據那麼就存在數據依賴。
·依賴問題在並行編程中是極其重要的,也是限制並行機制的主要因素。
Ø 例如:
·循環中的數據依賴:
DO 500 J = MYSTART,MYEND A(J) = A(J-1) * 2.0 500 CONTINUE |
A(J-1)的值必定要在計算A(J)值以前計算,所以A(J)的值依賴A(J-1)的值。不能並行。
若是任務2計算A(J),任務1計算A(J-1),想要獲得正確的A(J)的值必需要:
1)分佈式內存體系結構中,任務2必定要在任務1計算完A(J-1)的值後才能夠計算。
2)共享內存體系結構中,任務2必定要讀取任務1更新A(J-1)的值以後才能夠計算。
·循環獨立數據依賴
task 1 task 2 ------ ------
X = 2 X = 4 . . . . Y = X**2 Y = X**3 |
像前面的例子同樣,這個例子也是不能並行化的,Y值依賴於:
1)分佈式內存體系結構——X的值在任務之間是否通訊或者什麼時候通訊都存在必定的數據依賴。
2)共享內存體系結構——哪一個任務最後將X保存。
·當設計並行程序的時候,識別全部的數據依賴是很重要的。並行化的主要目標多是循環,因此識別循環中的依賴問題更爲重要。
Ø 如何處理數據依賴
·分佈式內存體系結構——在同步點上須要通訊數據。
·共享內存體系結構——在任務之間同步讀寫操做。
·負載平衡指的是使全部分佈式的工做高效運行、是CPU能夠保持較高的利用率較少的等待。也能夠看做是將任務空閒時間最小化的方法。
·對於提高系統性能來講,負載平衡是十分重要的。例如,全部的任務都要在障礙處同步,最慢的任務將決定全局的時間開銷。
Ø 如何得到負載平衡:
·平分每一個任務的工做量
1)對於數組或者矩陣操做,每一個任務分配類似的工做量,任務間平衡的分配數據。
2)對於循環迭代每一個迭代的工做量是類似的,給任務平均的分配迭代次數。
3)在異質的機器上性能特色各不相同,必定要用某種性能分析工具來測試負載平衡的性能,根據結果調節工做。
·動態工做分配
1)即便數據平均的分配到各個任務上去,仍是會存在必定的負載平衡問題。
稀疏數組——有些任務須要些非零數據而其餘任務的數據基本上都是零。
自適應網格——有些任務須要規劃本身的網絡,而其餘的任務不須要。
N-體模擬——有一些小塊工做可能須要從原任務分離整合到其餘任務中;這些佔用小工做的進程比其餘的進程須要更多的工做。
2)當進程完成任務的數量很難肯定或者不能夠預測的時候,使用調度線程池模型可能會有所幫助。當任務完成本身的工做後,它排隊去申請新的工做。
3)咱們有必要設計算法去檢查和處理在程序中動態的發生的負載不平衡現象。
Ø 計算通訊比(譯者註釋:一個任務用在計算上的時間除以任務間同步通訊所用的時間,比值大說明時間利用率高)
·在並行計算中,粒度是用來描述計算通訊比的十份量化的方法。
·計算時間一般與同步事件通訊的時間段不一樣。
Ø 細粒度的並行
·通訊處理時只能完成不多量的可計算工做。
·低的計算通訊率
·促進負載平衡
·意味着高通訊開銷,下降了性能提高的可能性。
·若是粒度過小極可能任務間的通訊和同步所須要的花費時間比用在計算上的還長。
Ø 粗粒度並行
·在每次通訊同步之間完成至關多的計算任務。
·高計算通訊率
·意味着更加可能進行性能提高。
·更難進行有效的負載平衡調度
Ø 哪一個更好?
·最高效的粒度是由算法和當前硬件平臺決定的。
·一般狀況下,通訊和同步的開銷很大程度上取決於執行速度,這樣使用粗粒度較好。
·細粒度並行機制能夠減小負載不平衡所帶來的開銷。
Ø 壞處
·I/O操做一般認爲是限制並行化的因素。
·適用於全部平臺的並行的I/O系統目前爲止尚不成熟。
·在全部任務都看到相同文件系統的環境中,寫操做可能致使文件寫覆蓋。
·文件服務器同時處理多線程讀請求的能力將會影響寫操做。
·I/O必定是經過網絡(NFS或者非本地文件系統)構建的,可能致使服務器性能瓶頸甚至文件服務器崩潰。
Ø 優勢
·並行文件系統有如下幾種:
1)GPFS:AIX(IBM)的通用的並行文件系統。
2)Lustre:Linux機羣(SUN微系統)。
3)PVFS/PVFS2:Linux機羣的虛擬並行文件系統(Clemson/Argonne/Ohio State/等)。
4)PanFS: Linux機羣的Panasas ActiveScale文件系統。
5)HP SFS:HP存儲工做可剪裁的文件系統。Lustre是HP的基於並行文件系統(Linux全局文件系統)的產品。
·並行I/O編程MPI接口規範從1996年開始發佈了第二個版本MPI-2。如今也能夠拿到生產商免費實現。
·選項:
1)若是你要訪問並行文件系統,你要好好研究一下。
2)規則1:儘可能減小全局的I/O。
3)限定工做中的某些任務的I/O操做,而後爲並行任務分配通訊數據。例如:任務1讀取輸入文件,而後和其餘任務通訊所須要的數據。一樣,任務1從其餘任務讀取所需的數據後再完成寫操做。
4)共享文件空間的分佈式內存系統,在本地完成I/O操做則不共享文件空間。例如:每一個處理器可能有可使用的臨時文件空間。在本身本地操做一般要比在網絡上完成I/O操做更加高效。
5)爲每一個任務的輸入輸出文件建立惟一的文件名。
Ø 阿姆達爾(Amdahl's)法則
·阿姆達爾法則指出加速比是由並行化代碼部分決定的。
1 speedup = -------- 1 - P |
·若是沒有代碼被並行化,P=0那麼加速比=1,沒有加速。
·若是全部的代碼都被並行化了,P=1,理論上加速比是無限的。
·若是50%的代碼並行化了,最大的加速比=2,意味着代碼比原來快了一倍
·引入處理器的數目完成並行操做的部分。關係描述模型以下:
1 speedup = ------------ P + S --- N |
P是並行部分比例,N是處理器數目,S的串行比
·顯然並行加速比是有極限的:例如:
speedup -------------------------------- N P = .50 P = .90 P = .99 ----- ------- ------- ------- 10 1.82 5.26 9.17 100 1.98 9.17 50.25 1000 1.99 9.91 90.99 10000 1.99 9.91 99.02 100000 1.99 9.99 99.90
|
·可是,確實有些問題能夠經過增長問題的規模來提升性能。例如:
1)2D的網格計算 85秒 85%
2)串行部分 15秒 15%
咱們經過加倍網絡的規格來增長問題的規模並將時間步長減半。結果應該是原來四倍的網格節點數目,兩倍數量的時間步長。計時結果以下:
1)2D網格計算 680秒 97.84%
2)串行部分 15秒 2.16%
·這個問題經過增長並行時間比例比固定比例並行時間的問題可擴展性更強。(譯者注:將並行計算和串行計算的百分數代入前面公式可知加速比有所提升,證實增長問題規模提升並行比例確實能夠提高性能。)
Ø 複雜性
·一般,並行應用程序要比相對應的串行應用程序複雜得多,多是在一個數量級上。不只僅要考慮多個指令流在同時執行,並且它們中間還有多個數據流。
·在軟件開發週期的每一部分中,程序員因程序複雜而花費的時間是能夠測量的。
1)設計
2)編碼
3)調試
4)較優
5)維護
·開發並行應用程序的時候特別是與人合做開發的時候,遵循標準的軟件開發實踐準則是必需的。
Ø 可移植性
·因爲MPI、POSIX、HPF、OpenMP等API的標準化,使得並行程序中的可移植性問題比前些年大大改善。
·全部串行程序的可移植性問題都歸因於將其並行化。例如,若是你使用生產商的增強的Fortran、C和C++時,可移植性將存在問題。
·儘管上訴幾個API存在標準,可是不少實現的細節倒是不一樣的,有時須要修改代碼才能實現可移植性。
·操做系統在代碼可移植性問題上扮演着重要的角色。
·硬件體系結構有很大差異也會影響可移植性。
Ø 所需資源
·並行的首要目標是減小執行過程當中的阻塞時間,可是爲了達到這個目的,須要更多的CPU時間。例如,並行代碼在八個處理器的內核上運行1個小時實際上用了8個小時的CPU時間。
·並行程序比串行程序所需的內存數量要大得多,這是因爲咱們須要備份數據,爲與並行相關的負載提供庫函數和子系統。
·小段的並行程序實際上在性能上要比類似的串行程序差。設置並行環境、任務建立、任務間的通訊和終止等所須要的開銷佔用了總開銷的絕大部分。
Ø 可擴展性
·並行程序性能的可擴展性的能力取決於一些相關的因素。只是簡單的增長更多的機器很難提升總體性能。
·算法也是可擴展性固有的限制因素。從某種意義上來講,增長更多的資源可能會致使性能降低。不少並行的解決方案在某種程度上顯示出這個問題。
·硬件因素在可擴展性方面扮演着重要的角色。例如:
1)SMP機器上的內存和CPU總線帶寬
2)通訊網絡帶寬
3)在特定的機器或機羣中能夠得到的內存大小
4)處理器速度
·並行支持庫和子系統軟件限制與應用程序的可擴展性。
·相比串行程序來講,並行程序的調試、監視、分析並行程序的執行更加困難。
·如今能夠得到不少監視程序執行和程序分析的工具。
·有些很是有用,有些還跨平臺。
·起點:
1)LC的「軟件和計算支持工具」網頁在computing.llnl.gov/code/content/software_tools.php
2)關於「高性能工具和技術」的白皮書有點過期可是極可能十分有用,它提到了不少工具,還提到不少性能相關可給代碼開發者應用的話題。能夠在這裏找到
computing.llnl.gov/tutorials/performance_tools/HighPerformanceToolsTechnologiesLC.pdf.
3)性能分析工具教程Performance Analysis Tools Tutorial
·還有不少工做沒有完成,特別是可擴展性領域。
·這個例子是計算兩維數組元素,這裏計算每一個數組元素彼此互不影響。
·串行程序順序的每次計算一個元素。
·串行代碼多是這樣的形式:
do j = 1,n do i = 1,n a(i,j) = fcn(i,j) end do end do |
·元素的計算彼此獨立,這就是「使人尷尬的」並行狀態。
·這個問題能夠密集的計算。
Ø 並行解決方案1
·數組元素是分散的,因此每一個進程都擁有本身的一部分數組(子數組)。
·獨立的數組元素計算確保了不須要任務間的數據通訊。
·用其餘的標準來肯定分配方案,例如:子數組劃分。最大緩存或內存利用率劃分。
·因爲經過子數組劃分方法是比較滿意的,這樣就要根據編程語言選擇分配方案。
·將數組分配完後,每一個任務都執行只和本身的數據通訊執行本身的代碼。例如:用Fortran塊分配:
do j = mystart, myend do i = 1,n a(i,j) = fcn(i,j) end do end do |
·注意:只有外層循環變量與串行的方案不一樣。
Ø 可能的解決方案
·用SPMD模型實現
·主線程初始化數組、發送信息給工做線程並接收計算返回結果。
·工做線程接受主線程分配任務的信息,完成本身要作的計算工做將結果發給主線程。
·使用Fortran存儲模式,完成數組的塊分配。
·僞代碼以下:紅色的部分與並行不一樣。
find out if I am MASTER or WORKER
if I am MASTER
initialize the array send each WORKER info on part of array it owns send each WORKER its portion of initial array
receive from each WORKER results
else if I am WORKER receive from MASTER info on part of array I own receive from MASTER my portion of initial array
# calculate my portion of array do j = my first column,my last column do i = 1,n a(i,j) = fcn(i,j) end do end do
send MASTER results
endif |
Example: MPI Program in Fortran
Ø 並行解決方案2:線程池
·這裏使用兩種線程:
1)主線程:
爲工做線程維護線程池
在必要的時候分配任務給工做線程
收集工做線程的計算返回的結果集。
2)工做線程:
從主線程處獲取任務
完成計算
將結果發送回主線程
·工做線程在運行以前不知道要處理那部分數組,也不知道他們要計算多少任務。
·在運行時,自動的負載平衡:處理速度快的任務將會作更多的工做。
·僞代碼以下:紅色高亮的與並行中不一樣
find out if I am MASTER or WORKER
if I am MASTER
do until no more jobs send to WORKER next job receive results from WORKER end do
tell WORKER no more jobs
else if I am WORKER
do until no more jobs receive from MASTER next job
calculate array element: a(i,j) = fcn(i,j)
send results to MASTER end do
endif |
Ø 討論
·在上面線程池例子中,每一個任務的工做室計算獨立的數組元素。這裏的計算通訊比是細粒度的。
·細粒度解決方案能夠減小任務空閒時間但帶來了更多的通訊開銷。
·更加理想的解決方案多是給每一個任務分配更多的工做來完成。恰到好處的任務量由問題決定。
·有不少種PI值計算方法。考慮下面的近似PI值方法。
1)在正方形中話一個圓;
2)在正方形內隨機生成點;
3)肯定即在正方形內又在圓形內點的數量;
4)在圓形內點的數量除以在正方形內點的數量,結果付給r;
5)PI約等於4r;
6)注意:生成更多的點近似度會更高;
·此過程串行僞碼:
npoints = 10000 circle_count = 0
do j = 1,npoints generate 2 random numbers between 0 and 1 xcoordinate = random1 ycoordinate = random2 if (xcoordinate, ycoordinate) inside circle then circle_count = circle_count + 1 end do
PI = 4.0*circle_count/npoints |
·注意:在執行這個循環中最花費時間的地方是執行循環。
·致使「使人尷尬的並行」的解決方案
高密度計算
最小化通訊
最少化I/O操做
Ø 並行解決方案:
·並行策略:把循環分塊給任務集執行。
·近似的PI
1)每一個任務執行一部分循環屢次。
2)每一個任務不須要從其餘的任務獲取任何信息就能夠完成本身工做。(沒有數據依賴)
3)使用SPMD模型。一個任務是主線程負責收集結果。
·僞代碼以下:紅色區是爲並行而加
npoints = 10000 circle_count = 0
p = number of tasks num = npoints/p
find out if I am MASTER or WORKER
do j = 1,num generate 2 random numbers between 0 and 1 xcoordinate = random1 ycoordinate = random2 if (xcoordinate, ycoordinate) inside circle then circle_count = circle_count + 1 end do
if I am MASTER
receive from WORKERS their circle_counts compute PI (use MASTER and WORKER calculations)
else if I am WORKER
send to MASTER circle_count
endif
|
Example: MPI Program in Fortran
·並行計算中的大多數問題都是須要進程間通訊的。一些常見的問題還須要和鄰居任務通訊。
·加熱等式描述的是溫度隨着時間而改變,初始化給出溫度分佈和邊界條件值。
·咱們用有限差分體系來解決在正方形區域上加熱等式量化的問題。
·邊界初始化溫度是零,中心溫度最高。
·外邊界溫度一直是零
·爲了詳細闡述這個問題咱們用了一個按時間分步的算法。兩維數組元素表明正方形中點的溫度。
·每個元素的計算都依賴與鄰居元素的值。
·串行代碼以下
do iy = 2, ny – 1 do ix = 2, nx - 1 u2(ix, iy) = u1(ix, iy) + cx * (u1(ix+1,iy) + u1(ix-1,iy) - 2.*u1(ix,iy)) + cy * (u1(ix,iy+1) + u1(ix,iy-1) - 2.*u1(ix,iy)) end do end do |
Ø 並行解決方案1
·用SPMD模型實施
·整個數組分組成子數組分配給全部的任務。每一個任務擁有整個數組的一部分。
·裁定數據依賴
迭代元素屬於自己任務而獨立於其餘任務。
邊界元素依賴鄰居任務數據,必須通訊。
·主線程發送消息給工做線程,檢查分塊位置和結果集。
·工做線程執行計算,和必要的鄰居通訊。
·僞代碼以下:紅色是並行實現所需:
find out if I am MASTER or WORKER
if I am MASTER initialize array send each WORKER starting info and subarray do until all WORKERS converge gather from all WORKERS convergence data broadcast to all WORKERS convergence signal end do receive results from each WORKER else if I am WORKER receive from MASTER starting info and subarray do until solution converged update time send neighbors my border info receive from neighbors their border info
update my portion of solution array
determine if my solution has converged send MASTER convergence data receive from MASTER convergence signal end do send MASTER results endif |
Ø 並行解決方案2:重疊的通訊和計算
·在前面的解決方案中,咱們假定工做線程使用的是阻塞通訊。阻塞通訊是等待通訊完成再執行下一條程序指令。
·在前面的解決方案中,鄰居任務通訊邊界數據,每一個進程更新本身那部分數組元素。
·使用非阻塞式通訊一般會減小計算時間。非阻塞通訊中通訊的同時能夠繼續工做。
·每一個任務更新本身的內部數組,同時邊界數據在通訊,通訊完成再更新邊界值。
·僞代碼:以下
find out if I am MASTER or WORKER
if I am MASTER initialize array send each WORKER starting info and subarray
do until all WORKERS converge gather from all WORKERS convergence data broadcast to all WORKERS convergence signal end do
receive results from each WORKER
else if I am WORKER receive from MASTER starting info and subarray
do until solution converged update time
non-blocking send neighbors my border info non-blocking receive neighbors border info
update interior of my portion of solution array wait for non-blocking communication complete update border of my portion of solution array
determine if my solution has converged send MASTER convergence data receive from MASTER convergence signal end do
send MASTER results
endif
|
·在這個例子中,振幅沿着一個統一的震動的軌跡每隔指定的時間計算一次。
·計算包括:
1)在Y軸上的振幅
2)沿着X軸的位置索引i
3)沿着軌跡上的節點
4)在離散的時間點更新振幅
·這裏要解的等式就是一維波等式。
A(i,t+1) = (2.0 * A(i,t)) - A(i,t-1) + (c * (A(i-1,t) - (2.0 * A(i,t)) + A(i+1,t)))
這裏C是常量
·注意:這裏的振幅依賴前面的時間段(t,t-1)和鄰居點(i-1 , i+1)。數據依賴意味着並行解決方案要引入通訊。
Ø 一維波並行解決方案
·用SPMD模型實現
·整個振幅數組被分割成子數組分配給每一個任務。每一個任務擁有整個數組的一部分。
·負載平衡:全部點的計算須要相同的工做量,因此點數應該平均分配。
·塊分解將按照塊大小分解任務,使得任務數和線程個數相等。讓每一個任務擁有大致上連續的數據點。
·只有數據邊界須要通訊。塊大小越大所需的通訊越少。
Ø 僞代碼解決方案以下:
find out number of tasks and task identities
#Identify left and right neighbors left_neighbor = mytaskid - 1 right_neighbor = mytaskid +1 if mytaskid = first then left_neigbor = last if mytaskid = last then right_neighbor = first
find out if I am MASTER or WORKER if I am MASTER initialize array send each WORKER starting info and subarray else if I am WORKER receive starting info and subarray from MASTER endif
#Update values for each point along string #In this example the master participates in calculations do t = 1, nsteps send left endpoint to left neighbor receive left endpoint from right neighbor send right endpoint to right neighbor receive right endpoint from left neighbor
#Update points along line do i = 1, npoints newval(i) = (2.0 * values(i)) - oldval(i) + (sqtau * (values(i-1) - (2.0 * values(i)) + values(i+1))) end do
end do
#Collect results and write to file if I am MASTER receive results from each WORKER write results to file else if I am WORKER send results to MASTER endif |
做者: Blaise Barney, 利弗莫爾計算中心。
譯者:盧洋,同濟大學
因爲譯者水平有限,翻譯中不免出現錯誤或遺漏歡迎你們指出。聯繫方式luyang.leon@gmail.com