• Aucun résultat trouvé

Building a Spanning Tree

Learning the Communication Graph

1.2 Parallel Traversal: Broadcast and Convergecast

1.2.4 Building a Spanning Tree

This section presents a simple algorithm that (a) implements broadcast and con-vergecast, and (b) builds a spanning tree. This algorithm is sometimes called prop-agation of information with feedback. Once a spanning tree has been constructed, it can be used for future broadcasts and convergecasts involving the same distin-guished processpa.

Local Variables As before, each process pi is provided with a set neighborsi which defines its position in the communication graph and, at the end of the execu-tion, its local variables parenti and childreni will define its position in the spanning tree rooted atpa.

To compute its position in the spanning tree rooted atpa, each processpi uses an auxiliary integer local variable denoted expected_msgi. This variable contains the number of messages thatpi is waiting for from its children before sending a messageBACK()to its parent.

Algorithm The broadcast/convergecast algorithm building a spanning tree is de-scribed in Fig.1.7. To simplify the presentation, it is first assumed that the channels are FIFO (first in, first out). The distinguished processpais the only process which receives the external messageSTART() (line1). Upon its reception,pa initializes parenta, childrenaand expected_msgaand sends a messageGO(data)to each of its neighbors (line2).

When a processpi receives a message GO(data)for the first time, it defines the senderpj as its parent in the spanning tree, and initializes childreni to∅ and expected_msgi the number of its neighbors minuspj (line 4). If its parent is its only neighbor, it sends back the pair(i, vi)thereby indicating topj that it is one of its children (lines5–6). Otherwise,pi forwards the messageGO(data)to all its neighbors but its parentpj (line7).

If parenti= ⊥, whenpi receivesGO(data), it has already determined its parent in the spanning tree and forwarded the messageGO(data). It consequently sends by return topj the messageBACK(), where∅is used to indicate topj thatpi is not one of its children (line9).

When a processpi receives a messageBACK(res,val_set)from a neighborpj, it decreases expected_msgi(line11) and addspj to childreni if val_set= ∅(line12).

Then, ifpi has received a messageBACK()from all its neighbors (but its parent, line13), it sends to its parent (lines15–16) the set val_set containing its own pair

1.2 Parallel Traversal: Broadcast and Convergecast 13 whenSTART()is received do % onlypareceives this message %

(1) parentii; childreni← ∅; expected_msgi← |neighborsi|; (2) for eachjneighborsidosendGO(data)topjend for.

whenGO(data)is received frompjdo (3) if(parenti= ⊥)

whenBACK(val_set)is received frompjdo (11) expected_msgiexpected_msgi1;

(12) if(val_set= ∅)then childrenichildreni∪ {j}end if;

(13) if (expected_msgi=0)then % a set val_setxhas been received from each childpx% (14) let val_set =(

xchildrenival_setx)∪ {(i, vi)}; letpr=parenti; (15) if(pr=i)

(16) thensendBACK(val_set)toppr % local termination forpi% (17) else pi(=pa) can computef (val_set) % global termination % (18) end if

(19) end if.

Fig. 1.7 Construction of a rooted spanning tree (code forpi)

(i, vi)plus all the pairs(k, vk)it has received from its children line14). Then,pi has terminated its participation in the algorithm (its local variable expected_msgi then becomes useless). Ifpi is the distinguished processpa, the set val_set contains a pair(x, vx)per processpx, andpa can accordingly computef (val_set)(where f ()is the function whose result is the output of the computation).

Let us notice that, when the distinguished processpa discovers that the algo-rithm has terminated, all the messages sent by the algoalgo-rithm have been received and processed.

Cost Let us observe that a messageBACK() is eventually sent as a response to each messageGO(). Moreover, except on the channels of the spanning tree that is built, two messagesGO() can be sent (one in each direction).

Letebe the number of channels of the underlying communication graph. It fol-lows that the algorithm gives rise to 2(n−1)messages which travel on the chan-nels of tree and 4(e−(n−1)) messages which travel on the other channels, i.e., 2(2e−n+1)messages. Then, once the tree is built, a broadcast/convergecast costs only 2(n−1)messages.

Assuming all messages take one time unit and local computations have zero du-ration, it is easy to see that the time complexity is 2DwhereDis the diameter of the communication graph. Once the tree is built, the time complexity of a

broad-Fig. 1.8 Left: Underlying communication graph; Right: Spanning tree

Fig. 1.9 An execution of the algorithm constructing a spanning tree

cast/convergecast is 2Da, where Da is the longest distance from pa to any other process.

An Example An execution of the algorithm described in Fig.1.7for the commu-nication graph depicted in the left part of Fig.1.8is described in Fig.1.9.

Figure1.9is a space-time diagram. The execution of a processpi, 1≤i≤4, is represented by an axis oriented from left to right. An arrow from one axis to another represents a message transfer. In this picture, an arrow labeledGOx,y()represents a messageGO()sent bypxtopy. Similarly, an arrow labeledBACKx,y()represents a messageBACK()sent bypxtopy.

The processp1 is the distinguished process that receives the external message

START()and consequently will be the root of the tree. It sends a messageGO() to its neighborsp2andp3. Whenp3receives this message, it defines its parent as being p1and forwards messageGO() to its two other neighborsp2andp4.

Since the first messageGO() received byp2is the one sent byp3,p2defines its parent as beingp3and forwards the messageGO() to its other neighbor, namelyp1. Whenp1receives a messageGO() fromp2, it sends back a message BACK(∅)to p2. In contrast, whenp4receives the messageGO() fromp3, it sends by return to p3a messageBACK()carrying the pair(4, v4). Moreover, whenp2has received a messageBACK()fromp1, it sends to its parentp3a messageBACK()carrying the pair(2, v2).

Finally, whenp3 receives the messages BACK()from p2 andp4, it discovers that these processes are its children and sends a messageBACK()carrying the set {(2, v2), (3, v3), (4, v4)}to its parentp1. Whenp1receives this message, it

discov-1.2 Parallel Traversal: Broadcast and Convergecast 15 ers thatp2is its only child. It can then computef ()on the vector[v1, v2, v3, v4].

The tree that has been built is represented at the right of Fig.1.8.

On the Parenthesized Structure of the Execution It is important to notice that the spanning tree that has been built depends on the speed of the messagesGO().

Another execution of the same algorithm on the same network with the same distin-guished process could produce a different tree rooted atp1.

It is also interesting to observe that each messageGO() can be seen as an opening bracket that can be associated with a messageBACK(), which is the corresponding closing bracket. This appears on the figure as follows:GOx,y()is an opening bracket whose associated closing bracket isBACKy,x().

The Case of Non-FIFO Channels Assuming non-FIFO channels and taking into account Fig.1.9, let us consider that the messageGO1,2() arrives atp2after the mes-sageBACK1,2(). It is easy to see that the algorithm remains correct (i.e., a spanning tree is built).

The only thing that changes is the meaning associated with line16. When a process sends a messageBACK() to its parent, it can no longer claim that its local computation is terminated. A process needs now to have received a message on each of its incident channels before claiming local termination.

A Spanning Tree per Process The algorithm of Fig.1.7can be easily general-ized to buildntrees, each one associated with a distinct process which is its dis-tinguished process. Then, when any processpi wants to execute an efficient broad-cast/convergecast, it has to use its associated spanning tree.

To build a spanning tree per process, the local variables parenti, childreni, and expected_msgi of each processpi have to be replaced by the arrays parenti[1..n], childreni[1..n]and expected_msgi[1..n]and all messages have to carry the identity of the corresponding distinguished process. More precisely, when a processpk re-ceives a messageSTART(), it uses its local variables parentk[k], childrenk[k], and expected_msgk[k]. The corresponding messages will carry the identityk,GO(k,) andBACK(k,), and, when a processpi receives such messages, it will uses its local variables parenti[k], childreni[k]and expected_msgi[k].

Concurrent Initiators for a Single Spanning Tree The algorithm of Fig.1.7can be easily modified to build a single spanning tree while allowing several processes to independently start the execution of the algorithm, each receiving initially a message

START(). To that end, each process manages an additional local variable max_idi

initialized to 0, which contains the highest identity of a process competing to be the root of the spanning tree.

• If a processpi receives a messageSTART()while max_idi =0,pi discards this message (in that case, it already participates in the algorithm but does not com-pete to be the root). Otherwise,pi starts executing the algorithm and all the cor-responding messagesGO()orBACK()carry its identity.

Fig. 1.10 Two different spanning trees built from the same communication graph

• Then, when a processpi receives a messageGO(j,−),pidiscards the message if j <max_idi. Otherwise,pi considerspj as the process with the highest identity which is competing to be the root. It sets consequently max_idi toj and con-tinues executing the algorithm by using messagesGO()andBACK()carrying the identityj.

It is easy to see that this simple application of the forward/discard strategy ensures that a single spanning tree will be constructed, namely the one rooted atpj wherej is such that, at the end of the execution, we have max_id1= · · · =max_idn=j.

Outline

Documents relatifs