MPI程式設計的常用介面速查
獲取當前時間
在插入MPI提供的標頭檔案後,可以獲得獲取時間的函式。
double MPI_Wtime(void) 取得當前時間, 計時的精度由 double MPI_Wtick(void) 取得 作為對比,一般在C/C++中, 插入time.h,通過 clock_t clock(void) 取得當前時間, 計時的精度由常數 CLOCKS_PER_SEC 定義。
點到點通訊函式
程序間的通訊需要通過一個通訊器來完成。MPI 環境在初始化時會自動建立兩個通訊器,一個稱為 MPI_COMM_WORLD,它包含程式中的所有程序,另一個稱為 MPI_COMM_SELF,它是每個程序獨自構成的、僅包含自己的通訊器。MPI 系統提供了一個特殊程序號 MPI_PROC_NULL,它代表空程序 (不存在的程序),與 MPI_PROC_NULL 進行通訊相當於一個空操 作,對程式的執行沒有任何影響。
使用MPI_Barrier(communicator)來完成同步
使用MPI_Send(message, size, data_type, dest_id, tag, communicator) 來把資料message封裝起來成為真正的訊息結構,向程序號為dest_id的程序傳送資料,是否要先把訊息存入緩衝區根據預設緩衝區的大小確定。
使用MPI_Bsend(message_data, size, data_type, dest_id, tag, communicator) 來發送資料,需要預先註冊一個緩衝區,並呼叫MPI_Buffer_attach(buffer, buf_size)來供MPI環境使用
使用MPI_Buffer_attach(buffer, size)來把緩衝區buffer提交給MPI環境,其中buffer是通過malloc分配的記憶體塊。
使用MPI_Buffer_detach(&buffer,&size)來確保傳輸的完成,儘量把detach和attach函式配對使用,正如儘可能同時使用malloc和free,同時使用Init和Finalize,防止遺漏!
使用MPI_Pack_size(size, data_type, communicator, &pack_size)來獲取包裝特定型別的資料所需要的緩衝區大小(還沒有計入頭部,所以真正緩衝區大小 buf_size = MPI_BSEND_OVERHEAD + pack_size,如果有多份資料傳送,則buf_size還要疊加)。
使用MPI_Recv(message, size, data_type, src_id, tag, communicator, status)來接收資料,把已經到達接收緩衝區的資料解析到message陣列中,只有全部資料都解析出來時,函式才返回。
tips:除了上述兩種傳送模式外,還有就緒通訊MPI_Rsend()和同步通訊MPI_Ssend(),引數都是一致的,函式的區別在於,如果已經保證接收動作在傳送動作之前啟動了(可以利用MPI_Barrier函式做到這一點),那麼就可以使用MPI_Rsend()提高效率;如果需要保證接收動作發生後,傳送動作才能返回,那麼就使用MPI_Ssend()
tips:上面都是阻塞通訊的方式,也就是呼叫這些函式的時候程序可能會阻塞。可以使用別的通訊模式,或者使用多執行緒來改變這一點。
集合通訊
MPI_Bcast廣播,使得資料有p份拷貝
MPI_Scatter散發,每份資料只拷貝一次
MPI_Gather收集,每份資料只拷貝一次
MPI_Reduce歸約
以後如果需要用到再寫吧。
資料型別和預定義的量
用於作為引數的資料型別 MPI_INT, MPI_DOUBLE, MPI_CHAR, MPI_Status
預定義的量 MPI_STATURS_IGNORE, MPI_ANY_SOURCE, MPI_ANY_TAG
初始化與結束
使用MPI_Init(&argc, &argv)來初始化MPI環境,可能是一些全域性變數的初始化。
使用MPI_Comm_rank(communicator, &myid)來獲取當前程序在通訊器中具有的程序號。
使用MPI_Comm_size(communicator, &numprocs)來獲取通訊器中包含的程序數目。
使用MPI_Finalize()來結束並行程式設計環境。之後我們就可以建立新的MPI程式設計環境了。