版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領
文檔簡介
1、1分布式系統(tǒng)開發(fā)計算機學院計算機科學與技術系計算機學院計算機科學與技術系主講:陳主講:陳 蕾蕾E-mail: 2第八章第八章 消息傳遞并行程序設計消息傳遞并行程序設計8.1 引言引言8.2 6個基本函數(shù)組成的個基本函數(shù)組成的MPI子集子集8.3 MPI消息消息8.4 點對點通信點對點通信8.5 群集通信群集通信38.1 引言引言MPI(Message Passing Interface )是一個消息傳遞接是一個消息傳遞接口標準,具有多種不同的免費、高效、實用的實現(xiàn)版本口標準,具有多種不同的免費、高效、實用的實現(xiàn)版本MPI提供一個可移植、高效、靈活的消息傳遞接口庫提供一個可移植、高效、靈活的消息
2、傳遞接口庫MPI以語言獨立的形式存在,可運行在不同的操作系統(tǒng)和以語言獨立的形式存在,可運行在不同的操作系統(tǒng)和硬件平臺上硬件平臺上幾乎所有的并行計算機廠商都提供對它的支持,成為了事幾乎所有的并行計算機廠商都提供對它的支持,成為了事實上的并行編程標準實上的并行編程標準MPI提供與提供與C和和Fortran語言的綁定語言的綁定4引言引言MPI標準產(chǎn)生于標準產(chǎn)生于1992年年4月月MPI是一個庫,而不是一門語言,因此對是一個庫,而不是一門語言,因此對MPI的使用必的使用必須和特定的語言結(jié)合起來進行須和特定的語言結(jié)合起來進行MPI的版本的版本MPICH:最重要的一種:最重要的一種MPI實現(xiàn),免費獲取網(wǎng)址
3、:實現(xiàn),免費獲取網(wǎng)址:/mpi/mpichLAM (Local Area Multicomputer):由美國:由美國Ohio State University 開發(fā),開發(fā),/downloadCHIMP:由:由Edinburgh大學開發(fā)的另外一個免費大學開發(fā)的另外一個免費MPI實現(xiàn),是實現(xiàn),是在在Edinburgh Parallel Computing Center的支持下進行的,的支持下進行的,ftp:/ftp.epcc.ed.ac.uk/pub/packages/chimp/release58.2
4、6個基本函數(shù)組成的個基本函數(shù)組成的MPI子集子集先看一個非常簡單的先看一個非常簡單的MPI程序例程序例1:#include mpi.h /*MPI頭函數(shù),提供了頭函數(shù),提供了MPI函數(shù)和數(shù)據(jù)類型的定義函數(shù)和數(shù)據(jù)類型的定義*/#include int main( int argc, char* argv ) int rank, size, tag=1; int senddata,recvdata; MPI_Status status; MPI_Init(&argc, &argv); /*MPI的初始化函數(shù)的初始化函數(shù)*/ MPI_Comm_rank(MPI_COMM_WORLD,
5、 &rank); /*該進程編號該進程編號*/ MPI_Comm_size(MPI_COMM_WORLD, &size); /*總的進程數(shù)目總的進程數(shù)目*/66個基本函數(shù)組成的個基本函數(shù)組成的MPI子集子集if (rank=0) senddata=9999; MPI_Send( &senddata, 1, MPI_INT, 1, tag, MPI_COMM_WORLD); /*發(fā)送數(shù)據(jù)到進程發(fā)送數(shù)據(jù)到進程1*/if (rank=1) MPI_Recv(&recvdata, 1, MPI_INT, 0, tag, MPI_COMM_WORLD, &stat
6、us); /*從進程從進程0接收數(shù)據(jù)接收數(shù)據(jù)*/MPI_Finalize(); /*MPI的結(jié)束函數(shù)的結(jié)束函數(shù)*/return (0);76個基本函數(shù)組成的個基本函數(shù)組成的MPI子集子集1、MPI初始化:通過初始化:通過MPI_Init函數(shù)進入函數(shù)進入MPI環(huán)境并環(huán)境并完成所有的初始化工作。完成所有的初始化工作。int MPI_Init( int *argc, char * * * argv )2、MPI結(jié)束:通過結(jié)束:通過MPI_Finalize函數(shù)從函數(shù)從MPI環(huán)境中環(huán)境中退出。退出。int MPI_Finalize(void)86個基本函數(shù)組成的個基本函數(shù)組成的MPI子集子集3、獲取進程
7、的編號:調(diào)用、獲取進程的編號:調(diào)用MPI_Comm_rank函數(shù)獲函數(shù)獲得當前進程在指定通信域中的編號,將自身與其他程得當前進程在指定通信域中的編號,將自身與其他程序區(qū)分。序區(qū)分。int MPI_Comm_rank(MPI_Comm comm, int *rank)4、獲取指定通信域的進程數(shù):調(diào)用、獲取指定通信域的進程數(shù):調(diào)用MPI_Comm_size函數(shù)獲取指定通信域的進程個數(shù),函數(shù)獲取指定通信域的進程個數(shù),確定自身完成任務比例。確定自身完成任務比例。int MPI_Comm_size(MPI_Comm comm, int *size)96個基本函數(shù)組成的個基本函數(shù)組成的MPI子集子集5、消
8、息發(fā)送:、消息發(fā)送:MPI_Send函數(shù)用于發(fā)送一個函數(shù)用于發(fā)送一個消息到目標進程。消息到目標進程。int MPI_Send(void *buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm) 該函數(shù)將起始地址為該函數(shù)將起始地址為buf的的count個個datatype類型類型的數(shù)據(jù)發(fā)送給目標進程,目標進程在通信域的數(shù)據(jù)發(fā)送給目標進程,目標進程在通信域comm中的編號由中的編號由dest標識。同時,發(fā)送方在發(fā)送該消息標識。同時,發(fā)送方在發(fā)送該消息時給它打上一個標簽時給它打上一個標簽tag,用于把本次發(fā)送的
9、消息,用于把本次發(fā)送的消息和本進程發(fā)送給同一目標進程的其他消息區(qū)分出來和本進程發(fā)送給同一目標進程的其他消息區(qū)分出來106、消息接受、消息接受:MPI_Recv函數(shù)用于從指定進程函數(shù)用于從指定進程接收一個消息接收一個消息int MPI_Recv(void *buf, int count, MPI_Datatype datatyepe,int source, int tag, MPI_Comm comm, MPI_Status *status);該函數(shù)從源進程接受一個消息,并且該消息的標簽該函數(shù)從源進程接受一個消息,并且該消息的標簽應該應該和參數(shù)應該應該和參數(shù)tag一致,源進程在通信域一致,源進程
10、在通信域comm中的編號由中的編號由source表示。消息接收后存放在起始地表示。消息接收后存放在起始地址為址為buf的接受緩沖區(qū)中,該緩沖區(qū)由的接受緩沖區(qū)中,該緩沖區(qū)由count個個datatype類型的連續(xù)數(shù)據(jù)元素組成;類型的連續(xù)數(shù)據(jù)元素組成;6個基本函數(shù)組成的個基本函數(shù)組成的MPI子集子集118.3 MPI消息消息一個消息好比一封信一個消息好比一封信消息的內(nèi)容即信的內(nèi)容,在消息的內(nèi)容即信的內(nèi)容,在MPI中稱為中稱為消息緩沖消息緩沖(Message Buffer)消息的接收者即信的地址,在消息的接收者即信的地址,在MPI中稱為中稱為消息信封消息信封(Message Envelop)12MP
11、I消息消息MPI中,消息緩沖由中,消息緩沖由三元組三元組標識標識消息信封由消息信封由三元組三元組標識標識 三元組的方式使得三元組的方式使得MPI可以表達更為豐富的信息,功可以表達更為豐富的信息,功能更強大能更強大 MPI_Send (buf, count, datatype, dest, tag, comm)消 息 緩 沖消 息 信 封13MPI消息消息(數(shù)據(jù)類型數(shù)據(jù)類型)MPI的消息類型分為兩種:的消息類型分為兩種:預定義類型預定義類型和和派生數(shù)據(jù)類型派生數(shù)據(jù)類型(Derived Data Type)預定義數(shù)據(jù)類型預定義數(shù)據(jù)類型:MPI支持異構(gòu)計算支持異構(gòu)計算(Heterogeneous C
12、omputing),它指在不同計算機系統(tǒng)上運行程序,每臺計,它指在不同計算機系統(tǒng)上運行程序,每臺計算機可能有不同生產(chǎn)廠商,使用不同的處理器和操作系統(tǒng),算機可能有不同生產(chǎn)廠商,使用不同的處理器和操作系統(tǒng),當這些計算機使用不同的數(shù)據(jù)表示時,如何保證通信雙方的當這些計算機使用不同的數(shù)據(jù)表示時,如何保證通信雙方的互操作性。互操作性。MPI通過提供預定義數(shù)據(jù)類型來解決異構(gòu)計算中的互操作性問題,通過提供預定義數(shù)據(jù)類型來解決異構(gòu)計算中的互操作性問題,建立它與具體語言的對應關系。建立它與具體語言的對應關系。派生數(shù)據(jù)類型派生數(shù)據(jù)類型:MPI引入派生數(shù)據(jù)類型來定義由數(shù)據(jù)類型不引入派生數(shù)據(jù)類型來定義由數(shù)據(jù)類型不同且
13、地址空間不連續(xù)的數(shù)據(jù)項組成的消息。同且地址空間不連續(xù)的數(shù)據(jù)項組成的消息。 14MPI預定義的數(shù)據(jù)類型預定義的數(shù)據(jù)類型表 2.1 MPI 中預定義的數(shù)據(jù)類型 MPI(C 語言綁定語言綁定) C C MPI(Fortran 語言綁定語言綁定) Fortran MPI_BYTE MPI_ BYTE MPI_CHAR signed char MPI_CHARACTER CHARACTER MPI_COMPLEX COMPLEX MPI_DOUBLE double MPI_DOUBLE_PRECISION DOUBLE_PRECISION MPI_FLOAT float MPI_REAL REAL MP
14、I_INT int MPI_INTEGER INTEGER MPI_LOGICAL LOGICAL MPI_LONG long MPI_LONG_DOUBLE long double MPI_PACKED MPI_PACKED MPI_SHORT short MPI_UNSIGNED_CHAR unsigned char MPI_UNSIGNED unsigned int MPI_UNSIGNED_LONG unsigned long MPI_UNSIGNED_SHORT unsigned short 15MPI附加數(shù)據(jù)類型附加數(shù)據(jù)類型MPI提供了兩個附加類型提供了兩個附加類型:MPI_BYT
15、E和和MPI_PACKED 。MPI_BYTE表示一個字節(jié),所有的計算系統(tǒng)中一個字表示一個字節(jié),所有的計算系統(tǒng)中一個字節(jié)都代表節(jié)都代表8個二進制位。個二進制位。MPI_PACKED預定義數(shù)據(jù)類型被用來實現(xiàn)傳輸?shù)刂奉A定義數(shù)據(jù)類型被用來實現(xiàn)傳輸?shù)刂房臻g不連續(xù)的數(shù)據(jù)項空間不連續(xù)的數(shù)據(jù)項 。16MPI消息消息(數(shù)據(jù)類型數(shù)據(jù)類型)例例2、使用、使用MPI_PACKED發(fā)送地址空間不連續(xù)數(shù)據(jù)項:發(fā)送地址空間不連續(xù)數(shù)據(jù)項: double A100;double A100; MPI_Pack_size MPI_Pack_size (50,MPI_DOUBLE, (50,MPI_DOUBLE, MPI_COMM
16、_WORLDMPI_COMM_WORLD,&BufferSize,&BufferSize);); TempBuffer = malloc(BufferSize TempBuffer = malloc(BufferSize);); j = sizeof(MPI_DOUBLE j = sizeof(MPI_DOUBLE);); Position = 0; Position = 0;for (i=0;i50;i+)for (i=0;i50;i+)MPI_Pack(A+2MPI_Pack(A+2* *i i* *j,1,MPI_DOUBLE,TempBuffer,BufferSize,
17、&Positj,1,MPI_DOUBLE,TempBuffer,BufferSize,&Position, ion, MPI_COMM_WORLDMPI_COMM_WORLD););MPI_Send(TempBuffer,Position,MPI_PACKED,destination,tagMPI_Send(TempBuffer,Position,MPI_PACKED,destination,tag, , MPI_COMM_WORLD);); 調(diào)用調(diào)用MPI_Pack_size函數(shù)來決定用于存放函數(shù)來決定用于存放50個個MPI_DOUBLE數(shù)據(jù)項數(shù)據(jù)項的臨時緩沖區(qū)的大小的臨時緩
18、沖區(qū)的大小 調(diào)用調(diào)用malloc函數(shù)為這個臨時緩沖區(qū)分配內(nèi)存函數(shù)為這個臨時緩沖區(qū)分配內(nèi)存 for循環(huán)中將數(shù)組循環(huán)中將數(shù)組A的的50個偶序數(shù)元素打包成一個消息并存放在臨時緩沖個偶序數(shù)元素打包成一個消息并存放在臨時緩沖區(qū)區(qū)17MPI消息消息(派生數(shù)據(jù)類型派生數(shù)據(jù)類型)派生數(shù)據(jù)類型可以用類型圖來描述,這是一種通用的類型描述方派生數(shù)據(jù)類型可以用類型圖來描述,這是一種通用的類型描述方法,它是一系列二元組法,它是一系列二元組的集合,可以表示成如的集合,可以表示成如下格式:下格式:,在派生數(shù)據(jù)類型中,基類型可以是任何在派生數(shù)據(jù)類型中,基類型可以是任何MPI預定義數(shù)據(jù)類型,也預定義數(shù)據(jù)類型,也可以是其它的派生
19、數(shù)據(jù)類型,即支持數(shù)據(jù)類型的嵌套定義??梢允瞧渌呐缮鷶?shù)據(jù)類型,即支持數(shù)據(jù)類型的嵌套定義。 如圖,陰影部分是基類型所占用的空間,其它空間可以是特意留如圖,陰影部分是基類型所占用的空間,其它空間可以是特意留下的,也可以是為了方便數(shù)據(jù)對齊。下的,也可以是為了方便數(shù)據(jù)對齊。基類型 0基類型 1基類型 i基類型 n-1偏移 0偏移 1偏移 i偏移 n-1類型圖的跨度類型圖的下界類型圖的上界偏移18MPI消息消息(數(shù)據(jù)類型數(shù)據(jù)類型)MPI提供了全面而強大的提供了全面而強大的構(gòu)造函數(shù)構(gòu)造函數(shù)(Constructor Function)來來定義派生數(shù)據(jù)類型。定義派生數(shù)據(jù)類型。 函數(shù)名含義MPI_Type_co
20、ntiguous定義由相同數(shù)據(jù)類型的元素組成的類型定義由相同數(shù)據(jù)類型的元素組成的類型MPI_Type_vector定義由成塊的元素組成的類型,塊之間具有相同間隔定義由成塊的元素組成的類型,塊之間具有相同間隔MPI_Type_indexed定義由成塊的元素組成的類型,塊長度和偏移由參數(shù)定義由成塊的元素組成的類型,塊長度和偏移由參數(shù)指定指定MPI_Type_struct定義由不同數(shù)據(jù)類型的元素組成的類型定義由不同數(shù)據(jù)類型的元素組成的類型MPI_Type_commit提交一個派生數(shù)據(jù)類型提交一個派生數(shù)據(jù)類型MPI_Type_free釋放一個派生數(shù)據(jù)類型釋放一個派生數(shù)據(jù)類型19MPI消息消息(數(shù)據(jù)類型
21、數(shù)據(jù)類型)例例3、使用派生數(shù)據(jù)類型發(fā)送地址空間不連續(xù)、使用派生數(shù)據(jù)類型發(fā)送地址空間不連續(xù)數(shù)據(jù)項:數(shù)據(jù)項: double A100; MPI_Data_type EvenElements; MPI_Type_vector(50, 1, 2, MPI_DOUBLE, &EvenElements); MPI_Type_commit(&EvenElements); MPI_Send(A, 1, EvenElements, destination, );首先聲明一個類型為首先聲明一個類型為MPI_Data_type的變量的變量EvenElements 調(diào)用構(gòu)造函數(shù)調(diào)用構(gòu)造函數(shù)MPI_Ty
22、pe_vector(count, blocklength, stride, oldtype, &newtype)來定義派生數(shù)據(jù)類型來定義派生數(shù)據(jù)類型 新的派生數(shù)據(jù)類型必須先調(diào)用函數(shù)新的派生數(shù)據(jù)類型必須先調(diào)用函數(shù)MPI_Type_commit獲得獲得MPI系統(tǒng)的確認后才能調(diào)用系統(tǒng)的確認后才能調(diào)用MPI_Send進行消息發(fā)送進行消息發(fā)送 20MPI消息消息(數(shù)據(jù)類型數(shù)據(jù)類型)調(diào)用構(gòu)造函數(shù)調(diào)用構(gòu)造函數(shù)MPI_Type_vector(count, blocklength, stride, oldtype, &newtype)來定義派生數(shù)據(jù)類型。來定義派生數(shù)據(jù)類型。該該newtype由由
23、count個數(shù)據(jù)塊組成。個數(shù)據(jù)塊組成。而每個數(shù)據(jù)塊由而每個數(shù)據(jù)塊由blocklength個個oldtype類型的連續(xù)數(shù)據(jù)項組成。類型的連續(xù)數(shù)據(jù)項組成。參數(shù)參數(shù)stride定義了兩個連續(xù)數(shù)據(jù)塊之間的定義了兩個連續(xù)數(shù)據(jù)塊之間的oldtype類型元素的個類型元素的個數(shù)。因此,兩個塊之間的間隔可以由數(shù)。因此,兩個塊之間的間隔可以由(stride-blocklength)來表來表示。示。MPI_Type_vector(50,1,2,MPI_DOUBLE,&EvenElements)函數(shù)調(diào)用產(chǎn)生了派生數(shù)據(jù)類型函數(shù)調(diào)用產(chǎn)生了派生數(shù)據(jù)類型EvenElements,它由,它由50個塊組成,個塊組成,每個
24、塊由一個雙精度數(shù)組成,后跟一個每個塊由一個雙精度數(shù)組成,后跟一個MPI_DOUBLE(8字節(jié)字節(jié))的的間隔,接在后面的是下一塊。間隔,接在后面的是下一塊。21MPI消息消息(消息標簽消息標簽)為什么需要為什么需要消息標簽消息標簽?當發(fā)送者連續(xù)發(fā)送兩個相同類型消息給同一個接收者,如果沒有當發(fā)送者連續(xù)發(fā)送兩個相同類型消息給同一個接收者,如果沒有消息標簽,接收者將無法區(qū)分這兩個消息消息標簽,接收者將無法區(qū)分這兩個消息 這段代碼打算傳送這段代碼打算傳送A的前的前32個字節(jié)進入個字節(jié)進入X,傳送,傳送B的前的前16個字節(jié)個字節(jié)進入進入Y。但是,盡管消息。但是,盡管消息B后發(fā)送,但可能先到達進程后發(fā)送,但
25、可能先到達進程Q,就會被,就會被第一個接收函數(shù)接收在第一個接收函數(shù)接收在X中。使用標簽可以避免這個錯誤中。使用標簽可以避免這個錯誤Process P:Send(A, 32, Q)Send(B, 16, Q)Process Q:recv (X, 32, P)recv (Y, 16, P)Process P:send(A, 32, Q, tag1)send(B, 16, Q, tag2)Process Q:recv (X, 32, P, tag1)recv (Y, 16, P, tag2)22MPI消息消息(消息標簽消息標簽)添加標簽使得服務進添加標簽使得服務進程可以對兩個不同的程可以對兩個不同的
26、用戶進程分別處理,用戶進程分別處理,提高靈活性提高靈活性例例4、一個簡單的處、一個簡單的處理客戶請求的情形理客戶請求的情形Process P: send (request1,32, Q ) Process R : send (request2, 32, Q ) Process Q : w hile (true) recv (received_request, 32, A ny_Process); process received_request; Process P: send(request1, 32, Q, tag1) Process R: send(request2, 32, Q, ta
27、g2) Process Q: while (true) recv(received_request, 32, Any_Process, Any_Tag, Status); if (Status.Tag=tag1) process received_request in one way; if (Status.Tag=tag2) process received_request in another way; 23MPI消息消息(通信域通信域)通信域(Communicator)包括包括進程組(Process Group)和和通信上下文(Communication Context)等等內(nèi)容,用于描
28、述通信進程間的通信關系。內(nèi)容,用于描述通信進程間的通信關系。通信域分為通信域分為組內(nèi)通信域組內(nèi)通信域和和組間通信域組間通信域,分別用來實現(xiàn),分別用來實現(xiàn)MPI的的組內(nèi)通信(Intra-communication)和和組間通信(Inter-communication)。24MPI消息消息(通信域通信域)進程組進程組是進程的是進程的有限、有序集有限、有序集。 有限意味著,在一個進程組中,進程的個數(shù)有限意味著,在一個進程組中,進程的個數(shù)n是有限的,這里是有限的,這里的的n稱為進程組大小稱為進程組大小(Group Size)。有序意味著,進程的編號是按有序意味著,進程的編號是按0,1,n-1排列的排列
29、的一個進程用它在一個通信域一個進程用它在一個通信域(組組)中的編號進行標識。中的編號進行標識。組的大小和進程編號可以通過調(diào)用以下的組的大小和進程編號可以通過調(diào)用以下的MPI函數(shù)獲函數(shù)獲得:得:MPI_Comm_size(communicator, &group_size)MPI_Comm_rank(communicator, &my_rank) 25MPI消息消息(通信域通信域)通信上下文通信上下文:安全的區(qū)別不同的通信以免相互干擾:安全的區(qū)別不同的通信以免相互干擾通信上下文不是顯式的對象,只是作為通信域的一部分出現(xiàn)通信上下文不是顯式的對象,只是作為通信域的一部分出現(xiàn)進程組和通
30、信上下文結(jié)合形成了進程組和通信上下文結(jié)合形成了通信域通信域MPI_COMM_WORLD是所有進程的集合,在執(zhí)行了是所有進程的集合,在執(zhí)行了MPI_Init函數(shù)之后自動產(chǎn)生,函數(shù)之后自動產(chǎn)生,MPI_COMM_WORLD只包含使用它的只包含使用它的進程進程 26MPI消息消息(通信域通信域)MPI提供豐富的函數(shù)用于管理通信域提供豐富的函數(shù)用于管理通信域 函數(shù)名含義MPI_Comm_size獲取指定通信域中進程的個數(shù)獲取指定通信域中進程的個數(shù)MPI_Comm_rank獲取當前進程在指定通信域中的編號獲取當前進程在指定通信域中的編號MPI_Comm_compare對給定的兩個通信域進行比較對給定的兩
31、個通信域進行比較MPI_Comm_dup復制一個已有的通信域生成一個新的通信域,兩復制一個已有的通信域生成一個新的通信域,兩者除通信上下文不同外,其它都一樣。者除通信上下文不同外,其它都一樣。MPI_Comm_create根據(jù)給定的進程組創(chuàng)建一個新的通信域根據(jù)給定的進程組創(chuàng)建一個新的通信域MPI_Comm_split從一個指定通信域分裂出多個子通信域,每個子從一個指定通信域分裂出多個子通信域,每個子通信域中的進程都是原通信域中的進程。通信域中的進程都是原通信域中的進程。MPI_Comm_free釋放一個通信域釋放一個通信域27MPI消息消息(通信域通信域)一個在一個在MPI中創(chuàng)建新通信域的例子
32、中創(chuàng)建新通信域的例子MPI_Comm MyWorld, SplitWorld;int my_rank,group_size, Color, Key;MPI_Init(&argc, &argv);MPI_Comm_dup(MPI_COMM_WORLD,&MyWorld);MPI_Comm_rank(MyWorld,&my_rank);MPI_Comm_size(MyWorld,&group_size);Color=my_rank%3;Key=my_rank/3;MPI_Comm_split(MyWorld,Color,Key,&SplitWorld
33、);28MPI消息消息(通信域通信域)MPI_Comm_dup(MPI_COMM_WORLD,&MyWorld)創(chuàng)建了一個新創(chuàng)建了一個新的通信域的通信域MyWorld,它包含了與原通信域,它包含了與原通信域MPI_COMM_WORLD相同相同的進程組,的進程組,但具有但具有不同的通信上下文。不同的通信上下文。MPI_Comm_split(MyWorld,Color,Key,&SplitWorld)函數(shù)調(diào)用則函數(shù)調(diào)用則在通信域在通信域MyWorld的基礎上產(chǎn)生了幾個分割的子通信域。原通信域的基礎上產(chǎn)生了幾個分割的子通信域。原通信域MyWorld中的進程按照不同的中的進程按照不同的
34、Color值處在不同的分割通信域中,每個值處在不同的分割通信域中,每個進程在不同分割通信域中的進程編號則由進程在不同分割通信域中的進程編號則由Key值來標識。值來標識。 Rank in MyWorld0123456789Color0120120120Key0001112223Rank in SplitWorld(Color=0)0123Rank in SplitWorld(Color=1)012Rank in SplitWorld(Color=2)01229MPI消息消息(通信域通信域)組間通信域組間通信域是一種特殊的通信域,該通信域包括了兩是一種特殊的通信域,該通信域包括了兩個進程組,分屬于
35、兩個進程組的進程之間通過組間通個進程組,分屬于兩個進程組的進程之間通過組間通信域?qū)崿F(xiàn)通信。信域?qū)崿F(xiàn)通信。一般把調(diào)用進程所在的進程組稱為本地進程組,而把一般把調(diào)用進程所在的進程組稱為本地進程組,而把另外一個稱為遠程進程組。另外一個稱為遠程進程組。 函數(shù)名含義MPI_Comm_test_inter判斷給定的通信域是否為組間通信域判斷給定的通信域是否為組間通信域MPI_Comm_remote_size獲取指定組間通信域中遠程進程組的大小獲取指定組間通信域中遠程進程組的大小MPI_Comm_remote_group返回給定組間通信域的遠程進程組返回給定組間通信域的遠程進程組MPI_Intercomm_
36、creat根據(jù)給定的兩個組內(nèi)通信域生成一個組間通信域。根據(jù)給定的兩個組內(nèi)通信域生成一個組間通信域。MPI_Intercomm_merge將給定組間通信域包含的兩個進程組合并,形成將給定組間通信域包含的兩個進程組合并,形成一個新的組內(nèi)通信域一個新的組內(nèi)通信域30MPI消息消息(消息狀態(tài)消息狀態(tài))消息狀態(tài)消息狀態(tài)(MPI_Status類型類型)存放接收消息的狀態(tài)信存放接收消息的狀態(tài)信息,包括消息的源進程標識(息,包括消息的源進程標識(MPI_SOURCE)、消)、消息標簽息標簽(MPI_TAG) 、包含的數(shù)據(jù)項個數(shù)、包含的數(shù)據(jù)項個數(shù)(count)以及以及消息的錯誤接受數(shù)目(消息的錯誤接受數(shù)目(MP
37、I_ERROR)它是消息接收函數(shù)它是消息接收函數(shù)MPI_Recv的最后一個參數(shù)的最后一個參數(shù)當一個接收者從不同進程接收不同大小和不同標簽的當一個接收者從不同進程接收不同大小和不同標簽的消息時,消息的狀態(tài)信息非常有用。消息時,消息的狀態(tài)信息非常有用。 31MPI消息消息(消息狀態(tài)消息狀態(tài))假設多個客戶進程發(fā)送消息給服務進程請求服務,通假設多個客戶進程發(fā)送消息給服務進程請求服務,通過消息標簽來標識客戶進程,從而服務進程采取不同過消息標簽來標識客戶進程,從而服務進程采取不同的服務的服務while (true) MPI_Recv(received_request,100,MPI_BYTE,MPI_An
38、y_source,M PI_Any_tag,comm,&Status);switch (Status.MPI_Tag) case tag_0: perform service type0; case tag_1: perform service type1; case tag_2: perform service type2; 328.4 點對點通信點對點通信MPI的點對點通信的點對點通信(Point-to-Point Communication )同時提供了阻塞和非阻塞兩種同時提供了阻塞和非阻塞兩種通信通信機制機制 。同時也支持多種同時也支持多種通信模式。通信模式。不同通信模式和不同
39、通信機制的結(jié)合,便產(chǎn)生了非常不同通信模式和不同通信機制的結(jié)合,便產(chǎn)生了非常豐富的點對點通信函數(shù)。豐富的點對點通信函數(shù)。33點對點通信點對點通信(通信模式通信模式)阻塞和非阻塞通信的主要區(qū)別在于返回后的阻塞和非阻塞通信的主要區(qū)別在于返回后的資源可用資源可用性性阻塞通信返回的條件:阻塞通信返回的條件:通信操作已經(jīng)完成通信操作已經(jīng)完成,及消息已經(jīng)發(fā)送或接收,及消息已經(jīng)發(fā)送或接收調(diào)用的緩沖區(qū)可用調(diào)用的緩沖區(qū)可用。若是發(fā)送操作,則該緩沖區(qū)可以被其它。若是發(fā)送操作,則該緩沖區(qū)可以被其它的操作更新;若是接收操作,該緩沖區(qū)的數(shù)據(jù)已經(jīng)完整,可的操作更新;若是接收操作,該緩沖區(qū)的數(shù)據(jù)已經(jīng)完整,可以被正確引用。以被
40、正確引用。 34點對點通信點對點通信(通信模式通信模式)通信模式通信模式(Communication Mode)指的是緩沖管理,指的是緩沖管理,以及發(fā)送方和接收方之間的同步方式。以及發(fā)送方和接收方之間的同步方式。 共有下面四種通信模式共有下面四種通信模式同步同步(synchronous)通信模式通信模式緩沖緩沖(buffered)通信模式通信模式標準標準(standard)通信模式通信模式就緒就緒(ready)通信模式通信模式35點對點通信點對點通信(通信模式通信模式)同步通信模式:同步通信模式:只有相應的接收過程已經(jīng)啟動,發(fā)送只有相應的接收過程已經(jīng)啟動,發(fā)送過程才正確返回。過程才正確返回。因
41、此,同步發(fā)送返回后,表示發(fā)送緩沖區(qū)中的數(shù)據(jù)已因此,同步發(fā)送返回后,表示發(fā)送緩沖區(qū)中的數(shù)據(jù)已經(jīng)全部被系統(tǒng)緩沖區(qū)緩存,并且已經(jīng)開始發(fā)送。經(jīng)全部被系統(tǒng)緩沖區(qū)緩存,并且已經(jīng)開始發(fā)送。當同步發(fā)送返回后,發(fā)送緩沖區(qū)可以被釋放或者重新當同步發(fā)送返回后,發(fā)送緩沖區(qū)可以被釋放或者重新使用。使用。SRSynchronous12336點對點通信點對點通信(通信模式通信模式)緩沖通信模式緩沖通信模式:緩沖通信模式的發(fā)送不管接收操作是緩沖通信模式的發(fā)送不管接收操作是否已經(jīng)啟動都可以執(zhí)行。否已經(jīng)啟動都可以執(zhí)行。但是需要用戶程序事先申請一塊足夠大的緩沖區(qū),通但是需要用戶程序事先申請一塊足夠大的緩沖區(qū),通過過MPI_Buff
42、er_attch實現(xiàn),通過實現(xiàn),通過MPI_Buffer_detach來回收申請的緩沖區(qū)。來回收申請的緩沖區(qū)。SRBuffer1237點對點通信點對點通信(通信模式通信模式)標準通信模式:標準通信模式:是否對發(fā)送的數(shù)據(jù)進行緩沖由是否對發(fā)送的數(shù)據(jù)進行緩沖由MPI的的實現(xiàn)來決定,而不是由用戶程序來控制。實現(xiàn)來決定,而不是由用戶程序來控制。發(fā)送可以是同步的或緩沖的,取決于實現(xiàn)發(fā)送可以是同步的或緩沖的,取決于實現(xiàn)StandardSR138點對點通信點對點通信(通信模式通信模式)就緒通信模式:就緒通信模式:發(fā)送操作只有在接收進程相應的接收發(fā)送操作只有在接收進程相應的接收操作已經(jīng)開始才進行發(fā)送。操作已經(jīng)開
43、始才進行發(fā)送。當發(fā)送操作啟動而相應的接收還沒有啟動,發(fā)送操作當發(fā)送操作啟動而相應的接收還沒有啟動,發(fā)送操作將出錯。就緒通信模式的特殊之處就是接收操作必須將出錯。就緒通信模式的特殊之處就是接收操作必須先于發(fā)送操作啟動。先于發(fā)送操作啟動。SRReady1239點對點通信點對點通信(通信模式通信模式)MPI的發(fā)送操作支持四種通信模式,它們與阻塞屬性的發(fā)送操作支持四種通信模式,它們與阻塞屬性一起產(chǎn)生了一起產(chǎn)生了MPI中的中的8種發(fā)送操作。種發(fā)送操作。而而MPI的接收操作只有兩種:阻塞接收和非阻塞接收。的接收操作只有兩種:阻塞接收和非阻塞接收。非阻塞通信返回后并不意味著通信操作的完成,非阻塞通信返回后并
44、不意味著通信操作的完成,MPI還提供了對非阻塞通信完成的檢測,主要的有兩種:還提供了對非阻塞通信完成的檢測,主要的有兩種:MPI_Wait函數(shù)和函數(shù)和MPI_Test函數(shù)。函數(shù)。 40點對點通信點對點通信(通信模式通信模式)MPI的點對點通信操作的點對點通信操作MPI 原語阻塞非阻塞Standard SendMPI_SendMPI_IsendSynchronous SendMPI_ SsendMPI_ IssendBuffered SendMPI_ BsendMPI_ IbsendReady SendMPI_ RsendMPI_ IrsendReceiveMPI_RecvMPI_IrecvCo
45、mpletion CheckMPI_WaitMPI_Test41 點對點通信點對點通信(通信模式通信模式)在阻塞通信的情況下,通信還沒有結(jié)束的時候,處理器只能等待,在阻塞通信的情況下,通信還沒有結(jié)束的時候,處理器只能等待,浪費了計算資源。浪費了計算資源。 一種常見的技術就是設法使計算與通信重疊,非阻塞通信可以用一種常見的技術就是設法使計算與通信重疊,非阻塞通信可以用來實現(xiàn)這一目的。來實現(xiàn)這一目的。 一條三進程的流水線,一個進程連續(xù)地從左邊的進程接收一個輸一條三進程的流水線,一個進程連續(xù)地從左邊的進程接收一個輸入數(shù)據(jù)流,計算一個新的值,然后將它發(fā)送給右邊的進程。入數(shù)據(jù)流,計算一個新的值,然后將它
46、發(fā)送給右邊的進程。 while (Not_Done) MPI_Irevc(NextX, );MPI_Isend(PreviousY, );CurrentY=Q(CurrentX);X=P(W)WY=Q(X)XZ=R(Y)YZ428.5 群集通信群集通信群集通信(Collective Communications)是一個進程是一個進程組中的所有進程都參加的全局通信操作。組中的所有進程都參加的全局通信操作。 群集通信一般實現(xiàn)三個功能:通信、聚集和同步。群集通信一般實現(xiàn)三個功能:通信、聚集和同步。 通信功能主要完成組內(nèi)數(shù)據(jù)的傳輸通信功能主要完成組內(nèi)數(shù)據(jù)的傳輸 聚集功能在通信的基礎上對給定的數(shù)據(jù)完成一
47、定的操作聚集功能在通信的基礎上對給定的數(shù)據(jù)完成一定的操作 同步功能實現(xiàn)組內(nèi)所有進程在執(zhí)行進度上取得一致同步功能實現(xiàn)組內(nèi)所有進程在執(zhí)行進度上取得一致 43群集通信群集通信,按照通信方向的不同,又可以分為三種:群集通信,按照通信方向的不同,又可以分為三種:一對多通信,多對一通信和多對多通信。一對多通信,多對一通信和多對多通信。 一對多通信:一對多通信:一個進程向其它所有的進程發(fā)送消息,一個進程向其它所有的進程發(fā)送消息,這個負責發(fā)送消息的進程叫做這個負責發(fā)送消息的進程叫做Root進程。進程。多對一通信多對一通信:一個進程負責從其它所有的進程接收消:一個進程負責從其它所有的進程接收消息,這個接收的進程
48、也叫做息,這個接收的進程也叫做Root進程。進程。 多對多通信多對多通信:每一個進程都向其它所有的進程發(fā)送或:每一個進程都向其它所有的進程發(fā)送或者接收消息。者接收消息。44群集通信類型類型函數(shù)名函數(shù)名含義含義通信通信MPI_Bcast一對多廣播同樣的消息一對多廣播同樣的消息MPI_Gather多對一收集各個進程的消息多對一收集各個進程的消息MPI_GathervMPI_Gather的一般化的一般化MPI_Allgather全局收集全局收集MPI_AllgathervMPI_Allgather的一般化的一般化MPI_Scatter一對多散播不同的消息一對多散播不同的消息MPI_ScattervM
49、PI_Scatter的一般化的一般化MPI_Alltoall多對多全局交換消息多對多全局交換消息MPI_AlltoallvMPI_Alltoall的一般化的一般化聚集聚集MPI_Reduce多對一歸約多對一歸約MPI_AllreduceMPI_Reduce的一般化的一般化MPI_Reduce_scatterMPI_Reduce的一般化的一般化MPI_Scan掃描掃描同步同步MPI_Barrier路障同步路障同步45群集通信廣播是一對多通信的典型例子,其調(diào)用格式如下:是一對多通信的典型例子,其調(diào)用格式如下:MPI_Bcast(Address, Count, Datatype, Root, Com
50、m)數(shù)據(jù)廣播進程A0A0A0A0A0A0A046群集通信廣播的特點廣播的特點標號為標號為Root的進程發(fā)送相同的消息給通信域的進程發(fā)送相同的消息給通信域Comm中中的所有進程。的所有進程。消息的內(nèi)容如同點對點通信一樣由三元組消息的內(nèi)容如同點對點通信一樣由三元組標識。標識。對對Root進程來說,這個三元組既定義了發(fā)送緩沖也定義進程來說,這個三元組既定義了發(fā)送緩沖也定義了接收緩沖。對其它進程來說,這個三元組只定義了接了接收緩沖。對其它進程來說,這個三元組只定義了接收緩沖收緩沖 47群集通信收集是多對一通信的典型例子,其調(diào)用格式下收集是多對一通信的典型例子,其調(diào)用格式下:MPI_Gather(Sen
51、dAddress, SendCount, SendDatatype,RecvAddress, RecvCount, RecvDatatype, Root, Comm)散播收集A0A1A2A3A4A5A0A1A2A3A4A5數(shù)據(jù)進程48群集通信收集的特點收集的特點在收集操作中,在收集操作中,Root進程從進程域進程從進程域Comm的所有進程的所有進程(包括它自已包括它自已)接收消息。接收消息。這這n個消息按照進程的標識個消息按照進程的標識rank排序進行拼接,然后存排序進行拼接,然后存放在放在Root進程的接收緩沖中。進程的接收緩沖中。接收緩沖由三元組接收緩沖由三元組標識,發(fā)送緩沖由三元組標識,
52、發(fā)送緩沖由三元組標識,標識,所有非所有非Root進程忽略接收緩沖。進程忽略接收緩沖。49群集通信散播也是一個一對多操作,其調(diào)用格式如下散播也是一個一對多操作,其調(diào)用格式如下:MPI_Scatter(SendAddress, SendCount, SendDatatype,RecvAddress, RecvCount, RecvDatatype, Root, Comm)散播收集A0A1A2A3A4A5A0A1A2A3A4A5數(shù)據(jù)進程50群集通信散播的特點散播的特點Scatter執(zhí)行與執(zhí)行與Gather相反的操作。相反的操作。Root進程給所有進程進程給所有進程(包括它自已包括它自已)發(fā)送一個不同
53、的消息,發(fā)送一個不同的消息,這這n (n為進程域為進程域comm包括的進程個數(shù)包括的進程個數(shù))個消息在個消息在Root進程的發(fā)送緩沖區(qū)中按進程標識的順序有序地存放。進程的發(fā)送緩沖區(qū)中按進程標識的順序有序地存放。每個接收緩沖由三元組每個接收緩沖由三元組標識,所有的非標識,所有的非Root進程忽略發(fā)送緩進程忽略發(fā)送緩沖。對沖。對Root進程,發(fā)送緩沖由三元組進程,發(fā)送緩沖由三元組標識。標識。51群集通信全局收集多對多通信的典型例子,其調(diào)用格式如下:全局收集多對多通信的典型例子,其調(diào)用格式如下:MPI_Allgather(SendAddress, SendCount, SendDatatype,Re
54、cvAddress, RecvCount, RecvDatatype, Comm)Allgather操作相當于每個進程都作為操作相當于每個進程都作為ROOT進程執(zhí)行了一次進程執(zhí)行了一次Gather調(diào)用,即每一個進程都按照調(diào)用,即每一個進程都按照Gather的方式收集來自所的方式收集來自所有進程有進程(包括自己包括自己)的數(shù)據(jù)。的數(shù)據(jù)。 A0B0C0D0E0F0A0B0C0D0E0F0A0B0C0D0E0F0A0B0C0D0E0F0A0B0C0D0E0F0A0B0C0D0E0F0全局收集A0B0C0D0E0F0數(shù)據(jù)進程52群集通信全局交換也是一個多對多操作,其調(diào)用格式如下全局交換也是一個多對多操
55、作,其調(diào)用格式如下:MPI_Alltoall(SendAddress, SendCount, SendDatatype,RecvAddress, RecvCount, RecvDatatype, Comm)全局交換A0A1A2A3A4A5B0B1B2B3B4B5C0C1C2C3C4C5D0D1D2D3D4D5E0E1E2E3E4E5F0F1F2F3F4F5A0B0C0D0E0F0A1B1C1D1E1F1A2B2C2D2E2F2A3B3C3D3E3F3A4B4C4D4E4F4A5B5C5D5E5F5數(shù)據(jù)進程53群集通信全局交換的特點全局交換的特點在全局交換中,每個進程發(fā)送一個消息給所有進程在全局
56、交換中,每個進程發(fā)送一個消息給所有進程(包包括它自已括它自已)。這這n (n為進程域為進程域comm包括的進程個數(shù)包括的進程個數(shù))個消息在它的個消息在它的發(fā)送緩沖中以進程標識的順序有序地存放。從另一個角發(fā)送緩沖中以進程標識的順序有序地存放。從另一個角度來看這個通信,每個進程都從所有進程接收一個消息,度來看這個通信,每個進程都從所有進程接收一個消息,這這n個消息以標號的順序被連接起來,存放在接收緩沖個消息以標號的順序被連接起來,存放在接收緩沖中。中。全局交換等價于每個進程作為全局交換等價于每個進程作為Root進程執(zhí)行了一次散播進程執(zhí)行了一次散播操作。操作。54群集通信同步功能同步功能用來協(xié)調(diào)各個
57、進程之間的進度和步伐用來協(xié)調(diào)各個進程之間的進度和步伐 。目前。目前MPI的實現(xiàn)中支持一個同步操作,即的實現(xiàn)中支持一個同步操作,即路障同步路障同步(Barrier)。路障同步的調(diào)用格式如下路障同步的調(diào)用格式如下:MPI_Barrier(Comm)在路障同步操作在路障同步操作MPI_Barrier(Comm)中,通信域中,通信域Comm中的中的所有進程相互同步。所有進程相互同步。在該操作調(diào)用返回后,可以保證組內(nèi)所有的進程都已經(jīng)執(zhí)行完在該操作調(diào)用返回后,可以保證組內(nèi)所有的進程都已經(jīng)執(zhí)行完了調(diào)用之前的所有操作,可以開始該調(diào)用后的操作。了調(diào)用之前的所有操作,可以開始該調(diào)用后的操作。55群集通信群集通信的
58、群集通信的聚合功能聚合功能使得使得MPI進行通信的同時完成一進行通信的同時完成一定的計算。定的計算。 MPI聚合的功能分三步實現(xiàn)聚合的功能分三步實現(xiàn)首先是通信的功能,即消息根據(jù)要求發(fā)送到目標進程,目標首先是通信的功能,即消息根據(jù)要求發(fā)送到目標進程,目標進程也已經(jīng)收到了各自需要的消息;進程也已經(jīng)收到了各自需要的消息;然后是對消息的處理,即執(zhí)行計算功能;然后是對消息的處理,即執(zhí)行計算功能;最后把處理結(jié)果放入指定的接收緩沖區(qū)。最后把處理結(jié)果放入指定的接收緩沖區(qū)。MPI提供了兩種類型的聚合操作提供了兩種類型的聚合操作: 歸約和掃描。歸約和掃描。 56群集通信歸約的調(diào)用格式如下歸約的調(diào)用格式如下:MPI
59、_Reduce(SendAddress, RecvAddress, Count, Datatype, Op, Root, Comm)歸約的特點歸約的特點歸約操作對每個進程的發(fā)送緩沖區(qū)歸約操作對每個進程的發(fā)送緩沖區(qū)(SendAddress)中的數(shù)據(jù)中的數(shù)據(jù)按給定的操作進行運算,并將最終結(jié)果存放在按給定的操作進行運算,并將最終結(jié)果存放在Root進程的接進程的接收緩沖區(qū)收緩沖區(qū)(RecvAddress)中。中。參與計算操作的數(shù)據(jù)項的數(shù)據(jù)類型在參與計算操作的數(shù)據(jù)項的數(shù)據(jù)類型在Datatype域中定義,歸域中定義,歸約操作由約操作由Op域定義。域定義。歸約操作可以是歸約操作可以是MPI預定義的預定義的,
60、也可以是用戶自定義的。也可以是用戶自定義的。歸約操作允許每個進程貢獻向量值,而不只是標量值,向量歸約操作允許每個進程貢獻向量值,而不只是標量值,向量的長度由的長度由Count定義。定義。57群集通信MPI預定義的歸約操作預定義的歸約操作操作含義操作含義MPI_MAX最大值最大值MPI_LOR邏輯或邏輯或MPI_MIN最小值最小值MPI_BOR按位或按位或MPI_SUM求和求和MPI_LXOR邏輯異或邏輯異或MPI_PROD求積求積MPI_BXOR按位異或按位異或MPI_LAND邏輯與邏輯與MPI_MAXLOC第一個最大值第一個最大值MPI_BAND按位與按位與MPI_MINLOC第一個最小值第一個最小值58群集通信掃描的調(diào)用格式如下:掃描的調(diào)用格式如下:MPI_scan(SendAddress, RecvAddress, Count, Datatype, Op, Comm)掃描的特點掃
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年度個人房屋租賃擔保合同模板4篇
- 2024蘋果加工副產(chǎn)品深加工技術研發(fā)合同3篇
- 2025年度彩色激光打印機租賃及升級服務合同模板3篇
- 雪人的創(chuàng)意課程設計
- 年度雕刻雕銑設備控制系統(tǒng)競爭策略分析報告
- 2025年獼猴桃種植技術培訓土地租賃與農(nóng)民增收合同4篇
- 2025年度個人二手房交易合同模板環(huán)保裝修服務版3篇
- 2025年離婚風險防范:協(xié)議離婚與訴訟離婚適用條件合同3篇
- 二零二五年度苗木出口業(yè)務代理銷售合同4篇
- 二零二五版智能門窗控制系統(tǒng)集成與安裝服務合同4篇
- 常見老年慢性病防治與護理課件整理
- 履約情況證明(共6篇)
- 云南省迪慶藏族自治州各縣區(qū)鄉(xiāng)鎮(zhèn)行政村村莊村名居民村民委員會明細
- 設備機房出入登記表
- 六年級語文-文言文閱讀訓練題50篇-含答案
- 醫(yī)用冰箱溫度登記表
- 零售學(第二版)第01章零售導論
- 大學植物生理學經(jīng)典05植物光合作用
- 口袋妖怪白金光圖文攻略2周目
- 光伏發(fā)電站集中監(jiān)控系統(tǒng)通信及數(shù)據(jù)標準
- 三年級下冊生字組詞(帶拼音)
評論
0/150
提交評論