• Aucun résultat trouvé

A trace-independent approach

Dans le document Message-Passing Systems (Page 184-200)

Chapter 7: Graph Algorithms

9.3 Breakpoint detection

9.3.3 A trace-independent approach

In this section we introduce three asynchronous algorithms for the detection of breakpoints.

One of the algorithms detects earliest disjunctive breakpoints, another detects earliest unconditional breakpoints, and the last one detects earliest conjunctive breakpoints whose corresponding conjunctive predicates are stable (in the sense of Chapter 6). As we remarked earlier in Section 9.3.1, not always is the requirement that an unconditional breakpoint be the earliest such breakpoint meaningful—in fact, it only makes sense when at least one node does not participate in the unconditional breakpoint. If such is not the case, then what the algorithm that we discuss achieves is the detection of the requested unconditional breakpoint. Another pertinent observation regarding the algorithms of this section is the assumed stability of the conjunctive predicate used to detect the conjunctive breakpoints.

This assumption simplifies matters tremendously, and it is in the wake of this simplicity that we adopt it. However, there do exist techniques to detect conjunctive breakpoints in the bsence of stability (as inSection 9.3.2), and at least a couple of recent algorithms that do not employ traces can be found in the literature.

In contrast with the detection procedure discussed in the previous section, which was based on a trace of a previous execution, the overall approach in this section does not depend on any trace, but rather attempts to detect the required breakpoint as the computation

progresses. As in the case of the global state recording discussed in Section 5.2.1, what we must handle is then the interaction of two computations on G. One of the computations is the computation proper, the one that progresses by the exchange of the already introduced comp_msg messages. The other computation is the computation for breakpoint detection, which, as in Section 5.2.1, must be endowed with certain privileges with respect to the former computation, because it must be able to inspect nodes' states in that computation as well as the flow of comp_msg's. In the case of Algorithm A_Record_Global_State, we were able to get away without being more specific about the way the two computations interacted, but in the present case we must face the need to provide some of the details, especially because the computation for breakpoint detection will have to be able to attach additional fields, in the form of parameters, to the comp_msg's that flow among nodes.

Let us then fill in some of the details on how the two computations interact. We begin by assuming that the message complexity of the computation proper is O(c(n, m)), or more succinctly O(c). Likewise, we assume that every node's local clock can only represent local times up to a value T (i.e., lti ≤ T for all ni ∊ N), which can be arbitrarily large but needs nevertheless be such that we can refer to it when assessing our algorithms' complexities.

The following is how we henceforth assume the computation proper and the detection algorithms to interact. At ni ∊ N, the actions of both computations exclude one another in time, as usual. For clarity, we view node ni as comprising two processes that can send messages to each other. One of the processes is referred to as pi, while the other is referred to as qi. For all ni ∊ N, process qi, is responsible for the detection algorithm, while process pi

is responsible for the computation proper. Process qi may send messages to every other

process qj such that nj ∊ Neigi and to pi, while process pi may only send messages to qi. In this way, qi, is capable of intercepting every comp_msg that pi sends or receives, for the purpose of detecting breakpoints. In doing so, qi may add fields to, or strip fields off, the comp_msg's that it intercepts. Of course, every comp_msg sent by pi must somehow contain an indication of which pj it is destined to, so that qi can forward it appropriately to qj. Process qi responds to messages it receives either on edges (ni, nj) ∊ E or "internally" from pi. When specifying the algorithms for breakpoint detection, we provide actions for process qi only, and then mentions to the set N0 never appear, as clearly actions performed by nodes in this set are actions of the computation proper.

Perhaps the most important assumption on how processes pi and qi interact is that the atomicity of pi's actions may be violated, in the following sense. Process qi is activated (and then pi is suspended, while lti remains constant) when lti becomes equal to lubi (in the case of unconditional breakpoints) or when the local predicate lpi becomes true (in the case of conditional breakpoints), or yet upon the sending by pi of a comp_msg or the arrival of a message from qj such that nj ∊ Neigi. What this amounts to is that qi has some sort of

"preemptive priority" over pi.

When evaluating our algorithms' complexities, this dual character of a node's behavior may at first seem confusing, so that it is advisable to spell out the criteria to be used right away.

All the complexity measures to be given in this section are measures related to the

breakpoint detection computation only, and then may involve messages sent especially for detection purposes as well as comp_msg's to which additional fields were attached (although in the latter case only the message and bit complexities are affected, not the global time complexity, which is already accounted for by the computation proper). Such measures are then aimed at capturing the "overhead" of breakpoint detection only.

Our algorithms for breakpoint detection are based on the following general approach. For 1 ≤ i ≤ n, process qi maintains an array gsi of length n representing its view of the global state to be detected. This array is initialized with zeroes (representing the earliest global state of the computation) and is updated when information is received concerning the other nodes' local unconditional breakpoints or local predicates. Such information is conveyed from node to node either by means of special broadcast messages or as additional fields attached to the comp_msg's that constitute the communication traffic of the computation proper. This information, when sent by qi, comprises the array gsi. and may, depending on the type of breakpoint to be detected, comprise additional data as well. In each of the cases we consider, this information is exchanged among nodes in such a way as to allow at least one node, say nk ∊ N, to detect locally that the breakpoint has occurred at the global state recorded in the current gsk maintained by qk, which is in all cases the earliest global state at which the breakpoint can be said to have occurred.

Let us now examine Algorithm A_Detect_DB ("DB" for Disjunctive Breakpoint) for the detection of disjunctive breakpoints. Such a breakpoint is a global state at which for at least one of the participating nodes the local predicate holds. Clearly, the earliest global state at which a disjunctive predicate holds does not

Figure 9.1In this figure, the solid segment in a process's horizontal line indicates the time interval during which the corresponding local predicate is true. The two cuts shown clearly correspond to global states, in fact earliest global states in which the disjunctive predicate holds.

have to be unique (Figure 9.1), as we mentioned in Section 9.3.1, so it is conceivable that more than one node detects the occurrence of the breakpoint, however at different global states.

Because of the inherent ease with which disjunctive predicates can be detected in a distributed fashion, Algorithm A_Detect_DB is quite straightforward. It does not employ any broadcast messages, and attaches the array gsi(lti), in addition to a "status bit" (to be discussed shortly), to the comp_msg's sent by process qi on behalf of pi. This array is identical to gsi in all components except the ith, which is given by lti. Our earlier assumptions

imply that the value of lti is in this case the local time at pi when it sent the message that qi

intercepted, and then corresponds to pi's local state immediately succeeding the sending of the message. The comp_msg's sent by qi are then sent as comp_msg ("status bit", gsi(lti)).

Likewise, when qi receives a message comp_msg ("status bit", gs) from qj such that njNeigi, it is comp_msg that gets forwarded to pi.

Attaching the modified gsi to comp_msg's is a procedure with important properties in the context of this section, not only for the algorithm we are beginning to present, but also for other algorithms presented in the sequel. We then pause briefly to introduce the following two supporting lemmas.

Lemma 9.1.

For all ni ∊ N, if gsi is a global state such that gsi[i] < lti and no message is received at pi at time t such that gsi[i] < t ≤lti, then gsi(lti) is also a global state.

Proof: dIf gsi(lti) is not a global state, then there must exist nk, n ∊ N such that a comp_msg was sent by pk strictly later than gsi(lti)[k] and received at p earlier than (or at) gsi(lti)[ℓ]. By the definition of gsi(lti), and by hypothesis, it follows that the message must have been sent later than gsi[k] and arrived at pℓ earlier than (or at) gsi[ℓ], and then gsi must not be a global state, which is a contradiction.

Lemma 9.2.

If and are global states, then the component-wise maximum of the two is also a global state.

Proof: Let be the component-wise maximum of and , and suppose that it is not a global state. Then there must exist nk, n ∊ N such that a message was sent by pk strictly later than [k]and received at pℓ earlier than (or at) [ℓ]. Because

and then must not be a global state if

Likewise, if then must not be a global state.

Either case yields a contradiction.

The essence of Algorithm A_Detect_DB is the following for ni ∊ N. Variable lpi is initialized with false at process pi, and is assumed never to become true if ni does not participate in the breakpoint. Whenever qi detects that lpi has become true, it sets gsi[i] to lti and declares the disjunctive breakpoint detected at the global state gsi. Because every comp_msg it received from qj such that nj ∊ Neigi prior to lti carried a copy of qj's view of the global state with jth component updated to the time the message was sent, gsi must indeed be a global state by Lemmas 9.1 and 9.2. In order to ensure that it is also an earliest global state with respect to the disjunctive predicate, the simple procedure we just described must only be allowed to be performed if no other node has already detected a global state that renders the one qi would detect not an earliest one. This is where the "status bit" comes in. This bit will indicate, upon arriving along with a comp_msg, whether any other such global state has already been detected.

Algorithm A_Detect_DB is presented next. Two additional variables employed by the algorithm are the Booleans foundi and found_elsewherei, both initially set to false, which indicate respectively whether qi has detected the disjunctive breakpoint and whether such a breakpoint has already been detected elsewhere so that the one detected by qi would necessarily not be an earliest one.

Algorithm A_Detect_DB:

Variables:

gsi[k] = 0 for all nk ∊ N;

foundi = false;

found_elsewherei = false.

Listing 9.8 Input:

msgi = nil.

Action when lpi becomes true:

if not (foundi or found_elsewherei) then begin

gsi[i] :=lti; foundi := true end.

Listing 9.9 Input:

msgi = comp_msg from pi to pj. Action:

Send comp_msg(foundi or found_elsewherei, gsi(lti)) to qj.

Listing 9.10 Input:

msgi = comp_msg(b, gs).

Action:

found_elsewherei := b or found_elsewherei; if not (foundi or found_elsewherei) then for k := 1 to n do

if gsi[k] < gs[k] then gsi[k] := gs[k];

Send comp_msg to pi.

The next theorem establishes the correctness of Algorithm A_Detect_DB. This theorem, like the others to follow in this section, state the equivalence of several conditions. The proof strategy in all theorems is then to show that the first condition implies the second, which implies the third, and so on, and finally that the last condition implies the first.

Theorem 9.3.

There exist i ∊ N and ≥ 0 such that the following three conditions are equivalent to one another for Algorithm A_Detect_DB.

(i) There exists a global state such that lpk = true at time [k]for at least one nk ∊ N.

(ii) foundi becomes true at time lti = t.

(iii) At time lti = t, gsi is the earliest global state at which lpk = true for at least one nk ∊ N.

Proof:

(i) → (ii):

At least one of the nodes nk for which lpk ever becomes true must by actions (9.9) and (9.10) have reached this state for the first time when found_elsewherek = false. The assertion then follows immediately by action (9.8), with ni being this particular node and t being the local time at which lpi becomes true for the first time.

(ii) → (iii):

By hypothesis and by action (9.8), found_elsewherei can only have become true after time t.

By Lemmas 9.1 and 9.2, the gsi produced by action (9.8), the gsi(lti) used in action (9.9), and the gsi yielded by action (9.10) must all be global states. As a consequence of this, by action (9.8) gsi is at time t a global state at which lpi = true. If gsi were not an earliest global state at which lpk = true for at least one nk ∊ N, then either found_elsewherei would by actions (9.9) and (9.10) have become true prior to t, and then foundi would be false at t, which is a contradiction, or lpk would for some nk ∊ N be true right from the start, which is ruled out by our assumption on the initial values of these variables.

(iii) → (i):

This is immediate.

Each of the O(c) comp_msg's carries an n-component array, each of whose components is an integer no larger than T, so the bit complexity of Algorithm A_Detect_DB is O(cn logT).

Because only comp_msg's are employed, the algorithm's message and global time complexity are of O(1). Each message reception requires O(n) comparisons, which is then the algorithm's local time complexity.

Detecting the other types of breakpoints we consider in this section is a considerably more intricate task in comparison with the detection of disjunctive breakpoints. These other cases comprise unconditional breakpoints and conjunctive breakpoints on stable conjunctive predicates, all of which require some sort of additional "global" information to be monitored. It is the propagation of this global information that makes use of the broadcast messages we introduced earlier.

In general, in addition to gsi process qi also maintains another array of Booleans with its local view of the global condition to be monitored and detected.

When disseminated by qi, this array is always accompanied by gsi as well, so that whenever qi, detects locally that the global condition has occurred (by examination of its array), it also associates the contents of gsi with the global state at which the condition occurred.

Messages of the broadcast type are sent by qi whenever ni is one of the nodes participating in the global condition to be detected and either its local unconditional breakpoint is reached (in the case of unconditional breakpoint detection) or its local predicate becomes true (in the case of the detection of conjunctive breakpoints). The broadcast we employ follows closely Algorithm A_PI of Section 4.1.1, but during the propagation of information an arriving gs from some process qj is used by qi to update gsi. In addition, gs and the other array accompanying it are used to update the local view at qi of the global condition being monitored.

What further differentiates the broadcast that we employ in this section from Algorithm A_PI is that we adopt a "forward-when-true" rule for the propagation of information. This rule states that a process participates in the broadcast (i.e., forwards the information it receives) only when its local condition (local unconditional breakpoint reached or local predicate become true) holds. Clearly, if no comp_msg's were ever sent, then this broadcast would suffice for the detection of the desired type of breakpoint. In such a case, whichever process produced an array with true values for all the participating processes would declare the breakpoint detected at the global state given by the global-state array obtained along with it.

Algorithm A_Broadcast_When_True does this detection in the absence of comp_msg's, so long as the global condition under monitoring is stable. In this algorithm, process pi maintains a Boolean variable lci to indicate whether the local condition with which ni participates (if at all) in the global condition to be detected is true. It is initialized with false if ni does indeed

participate in the global condition, or with true otherwise. Stability then means that no nk ∊ N exists such that lck is reset to false once it becomes true. The array associated with qi's view of the global condition is denoted by gci. For 1 ≤k ≤ n, gci[k] is initialized with the same value assigned initially to lck. Only broadcast messages are employed in this algorithm (as the computation proper does not employ any), and are sent as broadcast(gci, gsi) when qi is the sender. As in the case of Algorithm A_Detect_DB discussed earlier, a Boolean variable foundi, set to false initially, is employed to indicate whether qi has detected the occurrence of the global condition. In addition, another Boolean variable, changedi, is used by qi to ensure that a broadcast message is never sent to a node if not different than the last message sent to that node.

Algorithm A_Broadcast_When_True:

Variables:

gsi[k] = 0 for all nk ∊ N;

gci[k] for all nk ∊ N;

foundi = false;

changedi.

Listing 9.11 Input:

msgi = nil.

Action when lci becomes true:

gci[i] := lci; gsi[i] := lti;

if gci [1] … ∧ ∧gci[n] then foundi := true

else

Send broadcast (gci, gsi) to all qj such that nj ∊ Neigi.

Listing 9.12 Input:

msgi = (gc, gs).

Action:

if not foundi then begin

changedi := false;

for k := 1 to n do if gsi[k] < gs[k] then begin

gsi[k] := gs[k];

gci[k] := gc[k];

changedi := true end;

if lci and changedi then if gci[1] … ∧ ∧gci[n] then foundi := true

else

Send broadcast (gci, gsi) to all qj such that nj ∊ Neigi

end.

Properties of Algorithm A_Broadcast_When_True are given in the following theorem.

Theorem 9.4.

There exist ni ∊ N and t ≥ 0 such that the following three conditions are equivalent to one another for Algorithm A_Broadcast_When_True.

(i) There exists a global state such that lck = true at time [k] for all nk

∊ N.

(ii) foundi becomes true at time lti = t.

(iii) At time lti = t, gsi is the earliest global state at which lck = true for all nk N.

Proof:

(i) (ii):

If exactly one node participates in the global condition, then by action (9.11) foundi becomes true, with ni ∊ N being this node and t the time at which lci becomes true. No messages are ever sent in this case. If at least two nodes participate, then at least one of them, say nk ∊ N, is such that qk does by action (9.11) send a broadcast message to nk's neighbors when lck

becomes true, which by action (9.12) pass the updated information on, so long as the update introduced changes and their local conditions hold as well. Because this broadcast carries lck, it must introduce changes when reaching every node for the first time and is therefore propagated. This happens to the local condition of every participating node, and then at least one process, say qi, upon having been reached by their broadcasts, and having lci = true, sets foundi = true. The value of t here is either the time at which the last broadcast to reach qi does reach it by action (9.12) or the time at which lci becomes true by action (9.11).

(ii) (iii):

By Lemmas 9.1 and 9.2, the gsi produced in actions (9.11) and (9.12) are global states.

Consequently, and by actions (9.11) and (9.12) as well, at time t gsi is a global state at which lck = true for all nk ∊ N. That gsi is the earliest such global state is immediate, because of the absence of comp_msg's, which implies that gsi[k] is either zero or the time at which lck

Consequently, and by actions (9.11) and (9.12) as well, at time t gsi is a global state at which lck = true for all nk ∊ N. That gsi is the earliest such global state is immediate, because of the absence of comp_msg's, which implies that gsi[k] is either zero or the time at which lck

Dans le document Message-Passing Systems (Page 184-200)