localized fault recovery for nested fork-join programs

1
Localized Fault Recovery for Nested Fork-Join Programs High performance computers are increasingly susceptible to errors Periodic checkpointing is widely used approach to fault tolerance, but recovery cost can be proportional to system size it introduces large performance overhead We consider the design of fault tolerance mechanisms in the presence of fail-stop failures for nested fork-join programs, executed on distributed memory machines, load balancing provided by work stealing Problem Statement and Objectives Gokcen Kestor (Oak Ridge National Laboratory) Sriram Krishnamoorthy (Pacific Northwest National Laboratory), Wenjing Ma (Chinese Academy of Sciences) Introduction Reducing the amount of re-executed work in the presence of failures Guaranteeing forward progress even during fault recovery Ensuring correct interleaving of remote operations and error notifications Efficiently handling nested recovery, concurrent recovery, and failure- during-recovery scenarios Our Proposal: ForkJoinFT A modified distributed-memory algorithm that incorporates efficient fault recovery ForkJoinFT executes all and only lost work due to a fault, it needs to: 1. track the relationship between the subcomputations performed by different threads 2. reconstruct the relationship among live processes that have pending interactions with the failed node 3. re-execute all and only lost subcomputations without interfering with the normal task execution Nested fork-join models provide an opportunity to perform localizated fault recovery F(7) F(8) F(6) F(1) F(2) F(3) F(2) F(0) F(1) F(1) F(3) F(1) F(2) F(2) F(3) F(5) F(4) F(0) F(1) F(0) F(1) F(0) F(1) F(4) F(1) F(2) F(3) F(2) F(4) F(0) F(1) F(1) F(2) F(3) F(1) F(2) F(2) F(5) F(4) F(0) F(1) F(0) F(1) F(0) F(1) F(0) F(1) F(6) F(3) F(5) cont. cont. cont. A B C fib(n) { if ( n < 2 ) return n; a = fork fib(n-1); b = fork fib(n-2); join; return a + b; } We extended steal tree algorithm [PLDI’13] to retain only the live portion of subcomputations: each steal operation is identified with a unique ID (victim rank, working phase, level, and step) at every steal operation, the thief gets its victim steal path and adds the current steal operation all the preceded steals (Stolen Step) from a given victim in the same working phase are recorded Recovering Global Computation Tracking Global Computation Failure notifications are assumed to be sent to the server threads Upon a failure notification, each server thread independently initiates recovery: Identifies pending subcomputations stolen by the failed worker marks the victim of the failed worker as a recovery node requests steal tree paths that include the failed worker from all workers collects all steal tree paths and construct a replay tree the root of the replay tree is the subcomputation stolen by the failed worker collection is a distributed binary-tree-based reduction makes the replay tree and its root task ready to be stolen Scheduling Re-Execution When a thief steals work to be re-executed: its victim determines the task’s frontier task’s frontier is the failed worker’s list of alive children the thief assumes ownership of the root task of replay tree thieves of this subcomputation will return their results to new owner, rather than the failed worker Results The increase of total work time is generally less than 15% A regression analysis (OLS) models the relation between the number of re-executed tasks and the increase in work time reveals (sub) linear relationships Conclusions We presented an approach to localized fault recovery specific to nested fork-joined programs executed on distributed-memory systems Our fault tolerance approach: introduces negligible overhead of in the absence of faults, within the execution time variation re-executes all and only lost work due to faults significantly decreases the amount of work re-executed as compared to alternative strategies presents a recovery overhead roughly proportional to the amount of lost work A B C G F D E I H 0,0 1,0 0,0 1,0 2,0 0,0 1,1 2,1 0,0 1,0 2,0 3,0 ForkJoinFT re-executes only lost subcomputations Normal Execution Idle Recovery Execution Unsuccessful steal Privatization Patching Enforced steal Recovery done Empty frame returned Fork Merged frame returned Steal from replays Steal from deque Privatization: spawned task is not stolen in the failed execution, will be executed by the current worker Enforced steal: spawned task is stolen in the failed execution, will be donated to other thieves Patching: spawned task already exists in another live worker, no need to be executed 0.8 0.85 0.9 0.95 1 1.05 1.1 1.15 1.2 1024 2048 SCF 4096 1024 2048 TCE 4096 1024 2048 FIB 4096 1024 2048 BPC 4096 1024 2048 UTS 4096 Slowdown wrt baseline 32 nodes 64 nodes 128 nodes SCF 2.79 2.48 2.31 TCE 2.68 2.61 2.43 FIB 0.92 0.88 0.85 BPC 42.45 43.12 43.24 UTS 2.54 2.48 2.40 Table I: Space overhead per thread Negligible overhead and does not increase with core count Space overhead per thread is generally a few KB and remains roughly constant when scaling to larger node counts -10 -5 0 5 10 15 20 25 0 5 10 15 20 Total worktime increased (%) Tasks rexecuted (%) w/ 1024T w/ 2048T w/ 4096T Linear Reg. -10 -5 0 5 10 15 20 25 0 5 10 15 20 Total worktime increased (%) Tasks rexecuted (%) w/ 1024T w/ 2048T w/ 4096T Linear Reg. 10 20 30 40 50 60 70 80 1024 2048 SCF 4096 1024 2048 TCE 4096 1024 2048 FIB 4096 1024 2048 BPC 4096 1024 2048 UTS 4096 Task rexecuted (%) 32T failed 64T failed 128T failed 10 20 30 40 50 60 70 80 1024 2048 SCF 4096 1024 2048 TCE 4096 1024 2048 FIB 4096 1024 2048 BPC 4096 1024 2048 UTS 4096 Task rexecuted (%) 32T failed 64T failed 128T failed Average 3.1% Maximum 17% ForkJoinFT Average 18.3% Maximum 75% State-of-the-art Gokcen Kestor, Sriram Krishnamoorthy, Wenjing Ma, "Localized Fault Recovery for Nested Fork- Join Programs", IEEE International Parallel and Distributed Processing Symposium IPDPS 2017, pp. 397-408, May 2017, Orlando (FL).

Upload: others

Post on 01-Oct-2021

8 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Localized Fault Recovery for Nested Fork-Join Programs

Localized Fault Recovery for Nested Fork-Join Programs

• High performance computers are increasingly susceptible to errors • Periodic checkpointing is widely used approach to fault tolerance, but

– recovery cost can be proportional to system size – it introduces large performance overhead

• We consider the design of fault tolerance mechanisms in the presence of fail-stop failures for– nested fork-join programs, – executed on distributed memory machines,– load balancing provided by work stealing

Problem Statement and Objectives

Gokcen Kestor (Oak Ridge National Laboratory)Sriram Krishnamoorthy (Pacific Northwest National Laboratory), Wenjing Ma (Chinese Academy of Sciences)

Introduction

• Reducing the amount of re-executed work in the presence of failures • Guaranteeing forward progress even during fault recovery • Ensuring correct interleaving of remote operations and error

notifications • Efficiently handling nested recovery, concurrent recovery, and failure-

during-recovery scenarios

Our Proposal: ForkJoinFT

• A modified distributed-memory algorithm that incorporates efficient fault recovery

• ForkJoinFT executes all and only lost work due to a fault, it needs to:1. track the relationship between the subcomputations performed by

different threads2. reconstruct the relationship among live processes that have

pending interactions with the failed node3. re-execute all and only lost subcomputations without interfering

with the normal task execution

Nested fork-join models provide an opportunity to perform localizated fault recovery

F(7)

F(8)

F(6)

F(1)F(2)

F(3) F(2)

F(0)F(1)F(1)

F(3) F(1)F(2)F(2)

F(3)

F(5)

F(4)

F(0)F(1)F(0)F(1)

F(0)F(1)

F(4)

F(1)F(2)

F(3) F(2)

F(4)

F(0)F(1)F(1)F(2)

F(3) F(1)F(2)F(2)

F(5)

F(4)

F(0)F(1)

F(0)F(1)

F(0)F(1)

F(0)F(1)

F(6)

F(3)

F(5)

cont.cont.

cont.

A

B

C

fib(n){

if ( n < 2 )return n;

a = fork fib(n-1);b = fork fib(n-2);join;return a + b;

}

• We extended steal tree algorithm [PLDI’13] to retain only the live portion of subcomputations:– each steal operation is identified with a

unique ID (victim rank, working phase, level, and step)

– at every steal operation, the thief gets its victim steal path and adds the current steal operation

– all the preceded steals (Stolen Step) from a given victim in the same working phase are recorded

Recovering Global Computation

Tracking Global Computation

• Failure notifications are assumed to be sent to the server threads• Upon a failure notification, each server thread independently initiates

recovery:– Identifies pending subcomputations stolen by the failed worker– marks the victim of the failed worker as a recovery node– requests steal tree paths that include the failed worker from all

workers– collects all steal tree paths and construct a replay tree

• the root of the replay tree is the subcomputation stolen by the failed worker

• collection is a distributed binary-tree-based reduction– makes the replay tree and its root task ready to be stolen

Scheduling Re-Execution

• When a thief steals work to be re-executed:– its victim determines the task’s frontier– task’s frontier is the failed worker’s list of alive children– the thief assumes ownership of the root task of replay tree

• thieves of this subcomputation will return their results to new owner, rather than the failed worker

Results

• The increase of total work time is generally less than 15%• A regression analysis (OLS) models the relation between the number

of re-executed tasks and the increase in work time reveals (sub) linear relationships

Conclusions

• We presented an approach to localized fault recovery specific to nested fork-joined programs executed on distributed-memory systems

• Our fault tolerance approach: – introduces negligible overhead of in the absence of faults, within

the execution time variation– re-executes all and only lost work due to faults– significantly decreases the amount of work re-executed as

compared to alternative strategies– presents a recovery overhead roughly proportional to the amount of

lost work

A

B C

GFD E

IH

0,0

1,0

0,0

1,0

2,0

0,0

1,1

2,1

0,0

1,0

2,0

3,0

ForkJoinFT re-executes only lost subcomputations

Normal Execution

Idle Recovery Execution

Unsuccessful steal PrivatizationPatching

Enforced steal

Recovery done

Empty framereturned

Fork

Merged framereturned

Steal fromreplays

Steal from deque

Privatization: spawned task is not stolen in the failed execution, will be executed by the current workerEnforced steal: spawned task is stolen in the failed execution, will be donated to other thievesPatching: spawned task already exists in another live worker, no need to be executed

0.8

0.85

0.9

0.95

1

1.05

1.1

1.15

1.2

10242048SCF

4096 10242048TCE

4096 10242048FIB

4096 10242048BPC

4096 10242048UTS

4096

Slowdown wrt baseline

0.8

0.9

1

1.1

1.2

1.3

1.4

1024 2048SCF

4096 1024 2048TCE

4096 1024 2048FIB

4096 1024 2048BPC

4096 1024 2048UTS

4096

Slo

wd

ow

n w

rt b

as

eli

ne

no fault32T failed (31WT+1ST)

64T failed (62WT+2ST)128T failed (124WT+4ST)

Figure 10: Execution slowdown with the failure of one, two, or four computenodes (i.e., 31/1, 62/2, 124/4 failed worker/server threads, respectively) withrespect to the baseline algorithm for 1024, 2048, and 4096 threads.

32 nodes 64 nodes 128 nodes

SCF 2.79 2.48 2.31TCE 2.68 2.61 2.43FIB 0.92 0.88 0.85BPC 42.45 43.12 43.24UTS 2.54 2.48 2.40

Table I: Space overhead per thread(KB)

error is small even in a relatively high-fault system. Becauseof the randomness of our fault injection methodology andvariability in the execution due to random work stealing,we repeat each experiment 45 times and report average andstandard deviation.

A. Space and time overheadsFigure 10 (blue bars) shows the relative slowdown of

ForkJoinFT with respect to FORKJOIN when scaling from1024 (32 compute nodes) to 4096 threads (128 computenodes). We observe that the relative slowdown comparedto FORKJOIN does not increase with core count, and isnegligible, within the variations in the execution time.

To estimate the space overhead incurred, we tracked thesteal tree allocation and deallocation operations throughthe execution and report the maximum memory usage.Table I shows the space overhead per worker thread is smallcompared to the overall application memory footprint andremains roughly constant when scaling to larger node counts.BPC incurs a larger space overhead compared to the otherbenchmarks due to particularly narrow and long steal trees.

B. Execution slowdown due to faultsThe execution slowdown suffered by an application in a

faulty environment depends on three main factors: 1) thefraction of lost work, 2) the fraction of failed compute nodesand, 3) the time at which the fault is injected. The re-execution of the lost work is roughly proportional to theexecution slowdown, as the application has to perform extrawork. According to our fault model, failed node do notresume their execution. Thus, after the failure, the systemeffectively consists of fewer computing resources. Finally,if a fault occurs late during the execution, there might notbe enough task to distribute among the compute nodes, thusthe application’s critical path length may increase, resultingin further performance degradation.

Figure 10 shows that the relative increase in executiontime due to faults is very small and often below 10%(average slowdown), with the impact of each fault decreasing

with increase in system size. The execution time doesincrease when a larger number of compute nodes fail, as thefailed compute nodes do not participate in the computationafter the failure. With 4096 cores, the execution time withfault injection, on average, does not vary significantly fromfault-free execution. Since the number of failed threads isat most 3.2% of the total number of threads, there areenough compute resources to re-execute the lost computationbefore the end of the execution, so as to not significantlyimpact the overall execution time. However, there are casesin which the overhead is up to 20% (e.g., FIB with 12.5%of total number of threads failed). This is due to largeportion of computing resources unavailable after the failureand/or a late injection of faults during the execution of theapplication. We analyzed the data and observed that the runswith larger slowdown than average are those where faults areinjected late in the application’s execution.

C. Tasks re-executedTo understand the effectiveness of ForkJoinFT in mini-

mizing the re-execution cost, we report the average numberof tasks re-executed in Figure 11a. Because each applicationexecutes a different number of tasks, we report our resultsin terms of percentage of re-executed tasks relative to thenumber of tasks executed in a fault-free run. The errorsbars denote the standard deviation in percentage of re-executed tasks observed during the 45 runs. We observethat the amount of work re-executed is generally below 10%across all applications. The percentage of re-executed tasksgenerally increases with the number of failed worker threads,while decreasing with system size. This is consistent withour observations in Figure 10 and confirms the assumptionthat, for strong-scaling applications, the amount of worklost per thread, hence per compute node, decreases with theincrease in compute node count.

D. Relationship between tasks and work timeForkJoinFT minimizes the amount of re-execution rather

than directly manage total execution. Total execution time

• Negligible overhead and does not increase with core count • Space overhead per thread is generally a few KB and remains roughly

constant when scaling to larger node counts

-10

-5

0

5

10

15

20

25

0 5 10 15 20To

tal

wo

rkti

me

in

cre

as

ed

(%

)

Tasks rexecuted (%)

w/ 1024Tw/ 2048T

w/ 4096TLinear Reg.

-10

-5

0

5

10

15

20

25

0 5 10 15 20To

tal

wo

rkti

me

in

cre

as

ed

(%

)

Tasks rexecuted (%)

w/ 1024Tw/ 2048T

w/ 4096TLinear Reg.

10

20

30

40

50

60

70

80

1024 2048SCF

4096 1024 2048TCE

4096 1024 2048FIB

4096 1024 2048BPC

4096 1024 2048UTS

4096

Task rexecuted (%)

32T failed 64T failed 128T failed

10

20

30

40

50

60

70

80

1024 2048SCF

4096 1024 2048TCE

4096 1024 2048FIB

4096 1024 2048BPC

4096 1024 2048UTS

4096

Task rexecuted (%)

32T failed 64T failed 128T failed

Average 3.1% Maximum 17% ForkJoinFT

Average 18.3% Maximum 75% State-of-the-art

Gokcen Kestor, Sriram Krishnamoorthy, Wenjing Ma, "Localized Fault Recovery for Nested Fork-Join Programs", IEEE International Parallel and Distributed Processing Symposium IPDPS 2017, pp. 397-408, May 2017, Orlando (FL).