分散式計算課程補充筆記 part 2
▶ 平行計算八字原則:負載均衡,通訊極小
▶ 平行計算基本形式:主從並行、流水線並行、工作池並行、功能分解、區域分解、遞迴分治
▶ MPI 主要理念:程序 (process);無共享儲存;顯式訊息傳遞;鬆散同步 / 完全非同步;SPMD 方式程式設計
▶ MPI 的主要實現版本
● MPICH,Argonne 國家實驗室與 Mississippi 州立大學開發,是最早、最流行的實現
● MVAPICH,Ohio 州立大學開發,基於 MPICH,強調對各類硬體和網路的個性化支援。
● OpenMPI,Stuttgart 大學開發,多個 MPI 開源實現的合併版。
● Intel MPI,Cray MPI,HP-MPI,MS-MPI,……商業版本
▶ ABI 相容(application binary interface):由 MPICH 發起,保證各個MPI 實現在底層資料型別上的相容性
▶ 阻塞(blocking)與非阻塞(non-blocking)通訊(其他見 MPI 部分,這裡僅為補充)
● MPI_ISend() 與 MPI_IRecv(),非阻塞通訊未結束,不要修改 buf 中的傳送資料或使用 buf 中的接收資料
1 int MPI_Isend(void *buf, intcount, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm, MPI_Request *request) 2 int MPI_Irecv(void *buf, int count, MPI_Datatype datatype, int source, int tag, MPI_Comm comm, MPI_Request *request)
● 取消非阻塞通訊,需要傳入訊號標記
1 int MPI_Cancel(MPI_Request *request)
● 檢測非阻塞通訊是否已經結束,返回 flag==0 表示結束(即時返回)
1 int MPI_Test(MPI_Request *request, int *flag, MPI_Status *status)
● 等待非阻塞通訊結束(通訊結束後返回)
1 int MPI_Wait(MPI_Request *request, MPI_Status *status)
● 檢測 / 等待多個非阻塞通訊
1 int MPI_Testall(int count, MPI_Request requests[], int *flag, MPI_Status statuses[]) 2 int MPI_Waitall(int count, MPI_Request requests[], MPI_Status statuses[])
● 檢測/等待任一個非阻塞通訊
1 int MPI_Testany(int count, MPI_Request requests[], int *index, int *flag, MPI_Status *status) 2 int MPI_Waitany(int count, MPI_Request requests[], int *index, MPI_Status *status)
● 檢測/等待任一些非阻塞通訊
1 int MPI_Testsome(int incount, MPI_Request array_of_requests[], int *outcount, int array_of_indices[], MPI_Status array_of_statuses[]); 2 int MPI_Waitsome(int incount, MPI_Request array_of_requests[], int *outcount, int array_of_indices[], MPI_Status array_of_statuses[]);
● mpicc 的引數
1 -o # 指定輸出檔名,預設為 a.out 2 -g # 除錯選項,產生除錯資訊 3 -L # 指定連結庫路徑 4 -l # 指定連結庫的簡稱,如數學庫 -lm 5 -I # 指定標頭檔案路徑 6 -D # 相當於 C 語言裡面的巨集定義 7 -Wall # 開啟警告選項 8 -std # 指定 C 標準,如 -std=c99 使用 c99 標準
▶ 執行緒與程序的關係:執行緒可以被看作是程序的一部分,一個程序可以開啟多個執行緒;執行緒繼承了程序的資源 (比如指令、記憶體等);執行緒相互獨立的併發 (concurrent) 執行;對於單處理器核,多執行緒可以通過多工 (multi-tasking) 亦稱為時間切片 (time-slicing) 的方式由處理器輪流分時執行,此時也稱為軟體執行緒 (software threads)。
▶ OpenMP 要素和作用
● 執行時庫(run-time library)主要包括標頭檔案 (omp.h)、庫函式的呼叫和連結。
■ 用途:
Setting and querying the number of threads;
Querying thread ID, ancestor’s ID, and thread team size;
Setting and querying the dynamic threads feature;
Querying if in a parallel region, and at what level;
Setting and querying nested parallelism;
Setting, initializing and terminating locks and nested locks;
Querying wall clock time and resolution
● 環境變數(environment variable)預定義變數,執行時控制程式的行為。
■ 用途:
Setting the number of threads;
Specifying how loop interations are divided;
Binding threads to processors;
Enabling/disabling/setting nested parallelism;
Enabling/disabling dynamic threads;
Setting thread stack size and wait policy
● 編譯製導語句(compiler directive)特殊格式的註釋來實現功能,否則忽略。
■ 用途:
Spawning a parallel region;
Dividing blocks of code among threads;
Distributing loop iterations between threads;
Serializing sections of code;
Synchronization of work among threads
▶ if 從句:表示式為真則按照並行方式執行並行區,否則主執行緒序列執行並行區
▶按照優先順序從低到高,並行區中的執行緒數按照下面的順序確定:
● if 從句
● num_threads 從句設定
● omp_set_num_threads 庫函式設定
● OMP_NUM_THREADS 環境變數設定
● 系統預設(一般是可用的處理器核數)
▶ 考慮程式可以並行的條件。任給兩個程式 P1,P2,及各自輸入和輸出 I(P1),I(P2),O(P1),O(P2),有 Bernstein 條件:
▶ 序列一致性(sequential consistency)調整並行程式的語句順序,使得輸入不變時輸出也不變,則稱這種調整滿足序列一致性
▶ 基本依賴定理(Fundamental Theorem of Dependence)當且僅當程式中所有不可消除的資料依賴都得以滿足的條件下,並行程式的執行滿足序列一致性(一個需要排除的特例:規約)
● 三種基本資料依賴關係
■ 流依賴 (flow dependence):RAW = Read After Write,唯一一種不可消除的依賴
■ 反依賴 (anti-dependence): WAR = Write After Read
■ 輸出依賴 (output dependence): WAW = Write After Write
● 消除資料依賴:變數消去、變數私有化、變數替換、迴圈傾斜(loop skewing,調整每個迴圈內的操作,可能會有部分操作移到迴圈頭部或尾部以外)
▶ section 導語:對並行區內非迴圈任務多執行緒並行執行,每個程式段被執行一次,無法提前得知執行緒分配到的任務
1 #pragma omp sections [clause1 clause2 ...] 2 { 3 #pragma omp section 4 code1(); 5 #pragma omp section 6 code2(); 7 ... 8 }
▶ single 從句:對並行區內任務單執行緒執行,無法提前得知執行的執行緒,其他執行緒等待該執行緒執行完畢後進行同步,一般用於處理非執行緒安全(thread safe)的任務,如 I/O、共享變數賦值等
1 { 2 #pragma omp single [clause] 3 code(); 4 }
▶ nowait 從句:去掉工作共享構造末尾的隱式柵欄同步,可以用於 for、sections、single
▶ order 從句:序列執行 for 迴圈
▶ 從句支援
▶ 同步構造
● barrier 構造:柵欄同步
● single 構造:單執行緒執行,有同步
● master 構造:主執行緒執行,無同步
● critical 構造:依次執行,程式片段
● atomic 構造:依次執行,單一指令
▶ 鬆弛一致性 (relaxed consistency)
● OpenMP 的共享變數在本地快取中的修改並不隨時更新到記憶體,flush 從句用於手動更新當前執行緒本地快取中的資料。
● OpenMP 的一些同步操作隱含包含了 flush,如並行區 / critical 區入出口(注意工作共享構造的入口不隱含 flush),顯式 / 隱式的 barrier 操作等
● flush 一般置於共享變數的寫操作後或讀操作前
● 合理的演算法設計一般不需要顯式 flush
▶ 程式的遺孤 (orphaning)(?)
● 遺孤:“工作共享” 和 “同步” 可以放在並行區靜態範圍外;如果在動態範圍之內,則等同於非遺孤情況;否則,制導語句不起作用
● sections 構造不支援遺孤
▶ OpenMP 工作共享構造的缺陷
● 任務必須可數(for 迴圈或者 section 區塊),連結串列、遞迴等無法支援