1. 程式人生 > >分散式計算課程補充筆記 part 2

分散式計算課程補充筆記 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, int
count, 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 區塊),連結串列、遞迴等無法支援