【文章內(nèi)容簡(jiǎn)介】
d r e s s , c o u n t, d a ta ty p e )來(lái)定義 .第 ( 1 ) 個(gè)消息可以用 ( A , 1 0 0 , M P I _ D O U B L E ) 來(lái)定義 .第 ( 2 ) 個(gè)消息可以用 ( A +1 6 , 2 , M P I _ D O U B L E ) 來(lái)定義 .( 3 ) 由數(shù)組 A 的所有偶序數(shù)項(xiàng)組成的消息 .這個(gè)消息由 50 項(xiàng) A [ 0 ] , A [ 2 ] , A [ 4 ] , . . . , A [ 9 8 ] 組成 . 每一項(xiàng)有一個(gè) d o u b l e 數(shù)據(jù)類型 . 第 i 項(xiàng)的起始地址是 A +1 6 ( i 1 ) .( 4 )由數(shù)組 A 的第 3 項(xiàng) , 后跟一個(gè)字符 c , 再跟一個(gè)整型數(shù) k.這個(gè)消息由三個(gè)不同類型的數(shù)據(jù)組成 . 假定它是一個(gè)數(shù)據(jù)結(jié)構(gòu) :s t r u c t{ d o u b l e A [ 1 0 0 ] 。 c h a r b , c 。 i n t j, k 。} S的一部分 . 那么第一項(xiàng) A [ 2 ] 的地址是 S + 1 6 , 第二項(xiàng) c 的地址是 S + 8 0 1 , 第三項(xiàng) k 的地址是 S + 8 0 6 .第 ( 3 ) 個(gè)消息的性質(zhì) :數(shù)據(jù)項(xiàng)沒(méi)有放在一個(gè)連續(xù)的存儲(chǔ)區(qū)中 .第 ( 4 ) 個(gè)消息的性質(zhì) :數(shù)據(jù)不僅沒(méi)有連續(xù)存放 , 而且是混合數(shù)據(jù)類型 .上述簡(jiǎn)單的方法不能處理第 ( 3 ) 和第 (4) 個(gè)消息 .M P I 引入導(dǎo)出數(shù)據(jù)類型 ( d e r iv e d d a t a ty p e ) 的概念 , 允許定義可能是由混合數(shù)據(jù)類型 、 非連續(xù)存放的數(shù)據(jù)項(xiàng)組成的消息 . 導(dǎo)出數(shù)據(jù)類型由用戶的應(yīng)用程序在運(yùn)行時(shí)從基本的數(shù)據(jù)類型構(gòu)造 . M P I 提供了強(qiáng)大而全面的構(gòu)造復(fù)雜數(shù)據(jù)類型的子例程 .例 3 在消息傳遞中發(fā)送一個(gè)混合數(shù)據(jù)類型 國(guó)家高性能計(jì)算中心(合肥) 例 4 發(fā)送一數(shù)組的 所有偶序數(shù)元素 例 程 說(shuō) 明 M P I _D a t a _t y pe 聲明一個(gè)新的數(shù)據(jù)類型 E v e nEl e m e nt s . M P I _T y pe_v e c t o r( 50 ,1 ,2 ,M P I _ DOUB L E,amp。 Ev e nEl e m e nt s) 產(chǎn)生一個(gè)導(dǎo)出數(shù)據(jù)類型 Ev e nEl e m e nt s, 它由 50 個(gè)塊組成 . 每個(gè)塊的組成是一個(gè)雙精度數(shù) , 后跟一個(gè) 8 字節(jié)的間隔 , 接在后面的是下一塊 . st rid e 是兩個(gè)雙精度數(shù)的大小 , 即16 字節(jié) . 8 字節(jié)的間隔用于跳過(guò)數(shù)組 A 的奇序數(shù)元素 . M P I _T y pe_c o m m i t (amp。Ev e nEl e m e nt s) 這個(gè) 新類型必須在被發(fā)送例程使用前交付使用 . M P I _S e nd (A ,1 ,Ev e nEl e m e nt s, dest i nati o n, .. .) 注意 : E v e nEl e m e nt s 的一個(gè)元素包含 A 的所有 50 個(gè)偶序數(shù)元素 . 因此 , M P I _S e nd 的 c o un t 域值為 1. double A[100]。 MPI_Data_type EvenElements。 ... ... MPI_Type_vector(50,1,2,MPI_DOUBLE,amp。EvenElements)。 MPI_Type_mit(amp。EvenElements)。 MPI_Send(A,1,EvenElements,destination, ...)。 國(guó)家高性能計(jì)算中心(合肥) 說(shuō)明 : MPI_Type_vector(count, blocklength, stride, oldtype, amp。newtype) 是構(gòu)造導(dǎo)出數(shù)據(jù)類型的 MPI例程 . 導(dǎo)出類型 newtype由 blocks的拷貝 count份組成 . 每塊 (blocks)由已有的數(shù)據(jù)類型oldtype的 blocklength份連續(xù)項(xiàng)的拷貝組成 . stride定義每?jī)蓚€(gè)連續(xù)的塊之間的 oldtype元素個(gè)數(shù) . 因此 , (strideblocklength)即是兩個(gè)塊之間的間隔 . 1 MPI中的消息 國(guó)家高性能計(jì)算中心(合肥) 消息緩沖 (message buffer, 簡(jiǎn)稱 buffer), 在不同的消息傳遞使用場(chǎng)合有不同的含義 . 下面給出一些例子 : ? 消息緩沖指的是由程序員定義的應(yīng)用程序的存儲(chǔ)區(qū)域 , 用于存放消息的數(shù)據(jù)值 . 例如 , 在 Send(A, 16, Q, tag)中 , 緩沖 A是在用戶應(yīng)用程序中聲明的變量 . 該緩沖的起始地址在消息例程中被使用 . ? 消息緩沖也可以指由消息傳遞系統(tǒng) (而非用戶 )創(chuàng)建和管理的一些內(nèi)存區(qū) , 它用于發(fā)送消息時(shí)暫存消息 . 這種緩沖不在用戶的應(yīng)用程序中出現(xiàn) , 有時(shí)被稱為系統(tǒng)消息緩沖 (或系統(tǒng)緩沖 ). ? MPI允許第三種可能的定義 . 用戶可以劃出一定大小的內(nèi)存區(qū) , 作為出現(xiàn)在其應(yīng)用中的任意消息的中間緩沖 . 消息緩沖 1 MPI中的消息 國(guó)家高性能計(jì)算中心(合肥) 考慮下列代碼 , 由進(jìn)程 P傳送一個(gè)存放在數(shù)組 A中的消息 M, 到進(jìn)程 Q的數(shù)組 B中 . 例 5 在一對(duì)進(jìn)程間發(fā)送消息 1 MPI中的消息 國(guó)家高性能計(jì)算中心(合肥) Process P A M Process Q B Process P A M Process Q B S Process P A M Process Q B T (a) 只使用用戶緩沖 (b) 使用系統(tǒng)緩沖 S (c) 使用了用戶級(jí)的臨時(shí)緩沖 T Process P: double A[2022000]。 send(A,32,Q,tag)。 Process Q: double B[32]。 recv(B,32,P,tag) 國(guó)家高性能計(jì)算中心(合肥) 用戶如何來(lái)定義消息的接收者呢 ? 在下面列出的 MPI發(fā)送例程中 , 消息信封由三項(xiàng)組成 . MPI_Send (address, count, datatype, destination, tag, municator) destination 域是一個(gè)整數(shù) , 標(biāo)識(shí)消息的接收進(jìn)程 . 消息標(biāo)簽 (message tag), 也稱為消息類型 (message type), 是程序員用于標(biāo)識(shí)不同類型消息、限制消息接收者的一個(gè)整數(shù) . 2 MPI中的消息信封 國(guó)家高性能計(jì)算中心(合肥) 為什么要使用消息標(biāo)簽 (Tag)? P r o ce s s P : s en d (A, 3 2 ,Q ) s en d (B ,1 6 ,Q ) P r o ce s s Q : r ec v (X, 3 2 , P) r ec v (Y , 1 6 , P) 未使用標(biāo)簽 P r oce s s P : s e n d ( A,32 ,Q ,tag1) s e n d ( B ,1 6, Q ,tag2) P r oce s s Q : r e c v (X, 32, P , t ag 1) r e c v (Y , 16, P , t ag 2) 使用了標(biāo)簽 為了說(shuō)明為什么要用標(biāo)簽 , 我們先來(lái)看右面一段沒(méi)有使用標(biāo)簽的代碼 : 這段代碼打算傳送 A的前 32個(gè)字節(jié)進(jìn)入 X, 傳送 B的前 16個(gè)字節(jié)進(jìn)入 Y. 但是 , 如果消息 B盡管后發(fā)送但先到達(dá)進(jìn)程 Q,就會(huì)被第一個(gè) r e c v ( ) 接收在 X 中 . 使用標(biāo)簽可以避免這個(gè)錯(cuò)誤 . 2 MPI中的消息信封 國(guó)家高性能計(jì)算中心(合肥) 使用標(biāo)簽的另一個(gè)原因是可以簡(jiǎn)化對(duì)下列情形的處理 . 假定有兩個(gè)客戶進(jìn)程 P和 R, 每個(gè)發(fā)送一個(gè)服務(wù)請(qǐng)求消息給服務(wù)進(jìn)程 Q. 例 6 在消息傳遞中使用標(biāo)簽 P r oc e ss P : se n d ( r e q u e st 1, 32 , Q ) P r oc e ss R : se n d ( r e q u e st 2, 32 , Q ) P r oc e ss Q: w h il e ( t r u e ) { r e c v ( r e c e iv e d _r e q u e st , 32 , A n y _P r oc e ss) 。 p r oc e ss r e c e iv e d _r e q u e st 。 } P r oc e ss P : sen d (r e q u e st1, 32, Q, tag1) P r oc e ss R: sen d (r e q u e st2, 32, Q , tag2) P r oc e ss Q : w h i l e (t r u e ){ r e c v (r e c e i v e d _r e q u e st, 32, An y _P r oc e ss , An y _T ag, S tat u s)。 i f ( S tat u s. T ag== tag1) p r oc e ss r e c e i v e d _r e q u e st i n on e w ay 。 i f ( S tat u s. T ag== tag2) p r oc e ss r e c e i v e d _r e q u e st i n an oth e r w ay 。 } 未使用標(biāo)簽 使用了標(biāo)簽 國(guó)家高性能計(jì)算中心(合肥) 通信子 (municator): 一個(gè)進(jìn)程組 (process group)+上下文 (context). 進(jìn)程組 : 是進(jìn)程的有限有序集 . 有限意味著 , 在一個(gè)進(jìn)程組中 , 進(jìn)程的個(gè)數(shù) n是有限的 , 這里的 n稱為進(jìn)程組的大小 (group size). 有序意味著 n 個(gè)進(jìn)程是按整數(shù) 0, 1, ..., n1進(jìn)行編號(hào)的 . 一個(gè)進(jìn)程在一個(gè)通信子 (組 )中用它的編號(hào)進(jìn)行標(biāo)識(shí) . 組的大小和進(jìn)程編號(hào)可以通過(guò)調(diào)用以下的 MPI例程獲得 : MPI_Comm_size(municator, amp。group_size) MPI_Comm_rank(municator, amp。my_rank) 什么是通信子 ? 2 MPI中的消息信封 MPI_Send (address, count, datatype, destination, tag, municator) 國(guó)家高性能計(jì)算中心(合肥) 例 7 通信子的使用 2 MPI中的消息信封 Process 0: MPI_Send(msg1, count1, MPI_INT, 1, tag1, m1)。 parallel_fft(...)。 Process 1: MPI_Recv(msg1, count1, MPI_INT, 0, tag1, m1)。 parallel_fft(...)。 if (my_rank==0) MPI_Send(msg2, count1, MPI_INT,1,tag2,m2)。 含代碼 含代碼 國(guó)家高性能計(jì)算中心(合肥) 存在問(wèn)題 : 不可能保證 tag1 和 tag2一定取了不同的值 : ? 標(biāo)簽是由用戶定義的整數(shù)值 , 用戶可能會(huì)出錯(cuò) . ? 即使用戶不會(huì)弄錯(cuò) , 也難以或不可能保證 tag1 和 tag2有不同的值 . 函數(shù) parallel_fft( )可能是由其它用戶寫(xiě)的 , 或者它是一個(gè)庫(kù)例程 . 這樣 , 用戶可能不知道 tag2的值 . ? 即使用戶總能知道 tag2的值 , 仍然可能出錯(cuò) . 因?yàn)?MPI_Recv 例程可能決定使用一個(gè)通配的 (wildcard)標(biāo)簽 MPI_Any_tag. 解決辦法 : 在 parallel_fft( )中的通信使用不同的通信子 , 它可能包含相同的進(jìn)程組 (如 , 進(jìn)程 0和 1), 但每個(gè)通信子有系統(tǒng)指定的不同的上下文 , 與 m1的不同 . 因此 , MPI_Recv 不再有偶然會(huì)從 parallel_fft( )的 MPI_Send中接收 msg2的危險(xiǎn)了 . 2 MPI中的消息信封 國(guó)家高性能計(jì)算中心(合肥) 考慮如下由 10個(gè)進(jìn)程執(zhí)行的代碼 : 例 8 MPI中的新通信子 2 MPI中的消息信封 MPI_Comm MyWorld, SplitWorld。 int my_rank,group_size, Color, Key。 MPI_Init(amp。argc, amp。argv)。 MPI_Comm_dup(MPI_COMM_WORLD,amp。MyWorld)。 MPI_Comm_rank(MyWorld,amp。my_rank)。 MPI_Comm_size(MyWorld,amp。gro