Slide 1

Slide 1 text

MULTIWAY POWERSORT Ben Smith William Cawley Gelling, Markus E. Nebel, and Sebastian Wild University of Liverpool Monday 23rd January, 2023

Slide 2

Slide 2 text

TIMSORT AND POWERSORT ▶ Tim Peters introduced Timsort in 2002 • highly engineered version of mergesort • comparison based, internal, and stable • multiply adaptive: ▶ galloping merges ▶ run detection on the fly BEN SMITH WILLIAM CAWLEY GELLING, MARKUS E. NEBEL, AND SEBASTIAN WILD 1 / 16

Slide 3

Slide 3 text

TIMSORT AND POWERSORT ▶ Tim Peters introduced Timsort in 2002 • highly engineered version of mergesort • comparison based, internal, and stable • multiply adaptive: ▶ galloping merges ▶ run detection on the fly BEN SMITH WILLIAM CAWLEY GELLING, MARKUS E. NEBEL, AND SEBASTIAN WILD 1 / 16

Slide 4

Slide 4 text

TIMSORT AND POWERSORT ▶ Tim Peters introduced Timsort in 2002 • highly engineered version of mergesort • comparison based, internal, and stable • multiply adaptive: ▶ galloping merges ▶ run detection on the fly ▶ Timsort’s merge policy is less than optimal: • 1.5 times the optimal merge cost in the worst case (Buss and Knop 2018) • Hard to analyze • Prone to algorithmic bugs BEN SMITH WILLIAM CAWLEY GELLING, MARKUS E. NEBEL, AND SEBASTIAN WILD 1 / 16

Slide 5

Slide 5 text

TIMSORT AND POWERSORT ▶ Tim Peters introduced Timsort in 2002 • highly engineered version of mergesort • comparison based, internal, and stable • multiply adaptive: ▶ galloping merges ▶ run detection on the fly ▶ Timsort’s merge policy is less than optimal: • 1.5 times the optimal merge cost in the worst case (Buss and Knop 2018) • Hard to analyze • Prone to algorithmic bugs ▶ Munro and Wild introduced Powersort in 2018 • Merge policy update – retains most of Timsort • Optimal merge cost (up to lower order terms) • Built from first principles • Easy to analyze BEN SMITH WILLIAM CAWLEY GELLING, MARKUS E. NEBEL, AND SEBASTIAN WILD 1 / 16

Slide 6

Slide 6 text

TIMSORT AND POWERSORT ▶ Tim Peters introduced Timsort in 2002 • highly engineered version of mergesort • comparison based, internal, and stable • multiply adaptive: ▶ galloping merges ▶ run detection on the fly ▶ Timsort’s merge policy is less than optimal: • 1.5 times the optimal merge cost in the worst case (Buss and Knop 2018) • Hard to analyze • Prone to algorithmic bugs ▶ Munro and Wild introduced Powersort in 2018 • Merge policy update – retains most of Timsort • Optimal merge cost (up to lower order terms) • Built from first principles • Easy to analyze BEN SMITH WILLIAM CAWLEY GELLING, MARKUS E. NEBEL, AND SEBASTIAN WILD 1 / 16

Slide 7

Slide 7 text

MERGE COST AND MERGE ORDER ▶ Merge cost: An abstract cost measure introduced by Buss and Knop (2018) ▶ For a single operation merging k runs, r0, . . . , rk−1 , the merge cost is given by: M = |r0 | + . . . + |rk−1 | BEN SMITH WILLIAM CAWLEY GELLING, MARKUS E. NEBEL, AND SEBASTIAN WILD 2 / 16

Slide 8

Slide 8 text

MERGE COST AND MERGE ORDER ▶ Merge cost: An abstract cost measure introduced by Buss and Knop (2018) ▶ For a single operation merging k runs, r0, . . . , rk−1 , the merge cost is given by: M = |r0 | + . . . + |rk−1 | Merge order affects total merge cost (Example with k = 2) BEN SMITH WILLIAM CAWLEY GELLING, MARKUS E. NEBEL, AND SEBASTIAN WILD 2 / 16

Slide 9

Slide 9 text

MERGE COST AND MERGE ORDER ▶ Merge cost: An abstract cost measure introduced by Buss and Knop (2018) ▶ For a single operation merging k runs, r0, . . . , rk−1 , the merge cost is given by: M = |r0 | + . . . + |rk−1 | Merge order affects total merge cost (Example with k = 2) BEN SMITH WILLIAM CAWLEY GELLING, MARKUS E. NEBEL, AND SEBASTIAN WILD 2 / 16

Slide 10

Slide 10 text

MERGE COST AND MERGE ORDER ▶ Merge cost: An abstract cost measure introduced by Buss and Knop (2018) ▶ For a single operation merging k runs, r0, . . . , rk−1 , the merge cost is given by: M = |r0 | + . . . + |rk−1 | Merge order affects total merge cost (Example with k = 2) BEN SMITH WILLIAM CAWLEY GELLING, MARKUS E. NEBEL, AND SEBASTIAN WILD 2 / 16

Slide 11

Slide 11 text

MERGE COST AND MERGE ORDER ▶ Merge cost: An abstract cost measure introduced by Buss and Knop (2018) ▶ For a single operation merging k runs, r0, . . . , rk−1 , the merge cost is given by: M = |r0 | + . . . + |rk−1 | ▶ An optimal merge tree minimizes total merge cost ▶ Goal: A nearly optimal merge tree with low overhead costs Merge order affects total merge cost (Example with k = 2) BEN SMITH WILLIAM CAWLEY GELLING, MARKUS E. NEBEL, AND SEBASTIAN WILD 2 / 16

Slide 12

Slide 12 text

(2-WAY) POWERS AND THE VIRTUAL PERFECTLY BALANCED BINARY TREE 44 45 46 47 48 49 50 41 42 43 40 39 33 34 35 36 37 38 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 11 12 13 14 15 16 10 7 8 9 1 2 3 4 5 6 BEN SMITH WILLIAM CAWLEY GELLING, MARKUS E. NEBEL, AND SEBASTIAN WILD 3 / 16

Slide 13

Slide 13 text

(2-WAY) POWERS AND THE VIRTUAL PERFECTLY BALANCED BINARY TREE 44 45 46 47 48 49 50 41 42 43 40 39 33 34 35 36 37 38 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 11 12 13 14 15 16 10 7 8 9 1 2 3 4 5 6 5 4 5 3 5 4 5 2 5 4 5 3 5 4 5 1 5 4 5 3 5 4 5 2 5 4 5 3 5 4 5 BEN SMITH WILLIAM CAWLEY GELLING, MARKUS E. NEBEL, AND SEBASTIAN WILD 3 / 16

Slide 14

Slide 14 text

(2-WAY) POWERS AND THE VIRTUAL PERFECTLY BALANCED BINARY TREE 44 45 46 47 48 49 50 41 42 43 40 39 33 34 35 36 37 38 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 11 12 13 14 15 16 10 7 8 9 1 2 3 4 5 6 5 4 5 3 5 4 5 2 5 4 5 3 5 4 5 1 5 4 5 3 5 4 5 2 5 4 5 3 5 4 5 BEN SMITH WILLIAM CAWLEY GELLING, MARKUS E. NEBEL, AND SEBASTIAN WILD 3 / 16

Slide 15

Slide 15 text

(2-WAY) POWERS AND THE VIRTUAL PERFECTLY BALANCED BINARY TREE 44 45 46 47 48 49 50 41 42 43 40 39 33 34 35 36 37 38 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 11 12 13 14 15 16 10 7 8 9 1 2 3 4 5 6 5 4 5 3 5 4 5 2 5 4 5 3 5 4 5 1 5 4 5 3 5 4 5 2 5 4 5 3 5 4 5 BEN SMITH WILLIAM CAWLEY GELLING, MARKUS E. NEBEL, AND SEBASTIAN WILD 3 / 16

Slide 16

Slide 16 text

(2-WAY) POWERS AND THE VIRTUAL PERFECTLY BALANCED BINARY TREE 44 45 46 47 48 49 50 41 42 43 40 39 33 34 35 36 37 38 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 11 12 13 14 15 16 10 7 8 9 1 2 3 4 5 6 5 4 5 3 5 4 5 2 5 4 5 3 5 4 5 1 5 4 5 3 5 4 5 2 5 4 5 3 5 4 5 BEN SMITH WILLIAM CAWLEY GELLING, MARKUS E. NEBEL, AND SEBASTIAN WILD 3 / 16

Slide 17

Slide 17 text

(2-WAY) POWERS AND THE VIRTUAL PERFECTLY BALANCED BINARY TREE 44 45 46 47 48 49 50 41 42 43 40 39 33 34 35 36 37 38 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 11 12 13 14 15 16 10 7 8 9 1 2 3 4 5 6 5 4 5 3 5 4 5 2 5 4 5 3 5 4 5 1 5 4 5 3 5 4 5 2 5 4 5 3 5 4 5 BEN SMITH WILLIAM CAWLEY GELLING, MARKUS E. NEBEL, AND SEBASTIAN WILD 3 / 16

Slide 18

Slide 18 text

(2-WAY) POWERS AND THE VIRTUAL PERFECTLY BALANCED BINARY TREE 44 45 46 47 48 49 50 41 42 43 40 39 33 34 35 36 37 38 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 11 12 13 14 15 16 10 7 8 9 1 2 3 4 5 6 5 4 5 3 5 4 5 2 5 4 5 3 5 4 5 1 5 4 5 3 5 4 5 2 5 4 5 3 5 4 5 BEN SMITH WILLIAM CAWLEY GELLING, MARKUS E. NEBEL, AND SEBASTIAN WILD 3 / 16

Slide 19

Slide 19 text

(2-WAY) POWERS AND THE VIRTUAL PERFECTLY BALANCED BINARY TREE 44 45 46 47 48 49 50 41 42 43 40 39 33 34 35 36 37 38 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 11 12 13 14 15 16 10 7 8 9 1 2 3 4 5 6 5 4 5 3 5 4 5 2 5 4 5 3 5 4 5 1 5 4 5 3 5 4 5 2 5 4 5 3 5 4 5 BEN SMITH WILLIAM CAWLEY GELLING, MARKUS E. NEBEL, AND SEBASTIAN WILD 3 / 16

Slide 20

Slide 20 text

(2-WAY) POWERS AND THE VIRTUAL PERFECTLY BALANCED BINARY TREE 44 45 46 47 48 49 50 41 42 43 40 39 33 34 35 36 37 38 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 11 12 13 14 15 16 10 7 8 9 1 2 3 4 5 6 5 4 5 3 5 4 5 2 5 4 5 3 5 4 5 1 5 4 5 3 5 4 5 2 5 4 5 3 5 4 5 BEN SMITH WILLIAM CAWLEY GELLING, MARKUS E. NEBEL, AND SEBASTIAN WILD 3 / 16

Slide 21

Slide 21 text

(2-WAY) POWERS AND THE VIRTUAL PERFECTLY BALANCED BINARY TREE 3 4 5 2 1 3 2 4 3 44 45 46 47 48 49 50 41 42 43 40 39 33 34 35 36 37 38 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 11 12 13 14 15 16 10 7 8 9 1 2 3 4 5 6 5 4 5 3 5 4 5 2 5 4 5 3 5 4 5 1 5 4 5 3 5 4 5 2 5 4 5 3 5 4 5 BEN SMITH WILLIAM CAWLEY GELLING, MARKUS E. NEBEL, AND SEBASTIAN WILD 3 / 16

Slide 22

Slide 22 text

(2-WAY) POWERS AND THE VIRTUAL PERFECTLY BALANCED BINARY TREE 3 4 5 2 1 3 2 4 3 44 45 46 47 48 49 50 41 42 43 40 39 33 34 35 36 37 38 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 11 12 13 14 15 16 10 7 8 9 1 2 3 4 5 6 5 4 5 3 5 4 5 2 5 4 5 3 5 4 5 1 5 4 5 3 5 4 5 2 5 4 5 3 5 4 5 BEN SMITH WILLIAM CAWLEY GELLING, MARKUS E. NEBEL, AND SEBASTIAN WILD 3 / 16

Slide 23

Slide 23 text

(2-WAY) POWERS AND THE VIRTUAL PERFECTLY BALANCED BINARY TREE 3 4 5 2 1 3 2 4 3 44 45 46 47 48 49 50 41 42 43 40 39 33 34 35 36 37 38 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 11 12 13 14 15 16 10 7 8 9 1 2 3 4 5 6 5 4 5 3 5 4 5 2 5 4 5 3 5 4 5 1 5 4 5 3 5 4 5 2 5 4 5 3 5 4 5 BEN SMITH WILLIAM CAWLEY GELLING, MARKUS E. NEBEL, AND SEBASTIAN WILD 3 / 16

Slide 24

Slide 24 text

(2-WAY) POWERS AND THE VIRTUAL PERFECTLY BALANCED BINARY TREE 3 4 5 2 1 3 2 4 3 44 45 46 47 48 49 50 41 42 43 40 39 33 34 35 36 37 38 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 11 12 13 14 15 16 10 7 8 9 1 2 3 4 5 6 5 4 5 3 5 4 5 2 5 4 5 3 5 4 5 1 5 4 5 3 5 4 5 2 5 4 5 3 5 4 5 BEN SMITH WILLIAM CAWLEY GELLING, MARKUS E. NEBEL, AND SEBASTIAN WILD 3 / 16

Slide 25

Slide 25 text

POWERS ARE LOCAL 4 44 45 46 47 48 49 50 41 42 43 40 39 33 34 35 36 37 38 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 11 12 13 14 15 16 10 7 8 9 1 2 3 4 5 6 5 4 5 3 5 4 5 2 5 4 5 3 5 4 5 1 5 4 5 3 5 4 5 2 5 4 5 3 5 4 5 BEN SMITH WILLIAM CAWLEY GELLING, MARKUS E. NEBEL, AND SEBASTIAN WILD 4 / 16

Slide 26

Slide 26 text

CALCULATING MERGE POWERS ▶ For run lengths L0, . . . , Lr−1, first set li = Li n , then: • Define ai , the normalized centre of the (i − 1)st run: ai = i−1 j=0 lj − 1 2 li−1, • Define bi , the normalized centre of ith run: bi = i−1 j=0 lj + 1 2 li • Hence, define the power of the boundary between these runs, Pk i : Pk i = min{p ∈ N : ⌊ai · kp⌋ < ⌊bi · kp⌋} BEN SMITH WILLIAM CAWLEY GELLING, MARKUS E. NEBEL, AND SEBASTIAN WILD 5 / 16

Slide 27

Slide 27 text

2-WAY POWERSORT 1 procedure Powersort(𝐴[0..𝑛)) 2 𝑖 := 0; runs := new Stack() 3 𝑗 := ExtendRunRight(𝐴, 𝑖) 4 runs.push(𝑖, 𝑗); 𝑖 := 𝑗 5 while 𝑖 < 𝑛 6 𝑗 := ExtendRunRight(𝐴, 𝑖) 7 𝑝 := power(runs.top(), (𝑖, 𝑗), 𝑛) 8 while 𝑝 ≤ topmost power 9 merge topmost 2 runs 10 runs.push(𝑖, 𝑗); 𝑖 := 𝑗 11 while runs.size() ≥ 2 12 merge topmost 2 runs a b c d e f 24 25 26 27 28 21 22 23 18 19 20 4 5 6 7 8 9 10 11 12 13 14 15 16 17 3 1 2 BEN SMITH WILLIAM CAWLEY GELLING, MARKUS E. NEBEL, AND SEBASTIAN WILD 6 / 16

Slide 28

Slide 28 text

2-WAY POWERSORT 1 procedure Powersort(𝐴[0..𝑛)) 2 𝑖 := 0; runs := new Stack() 3 𝑗 := ExtendRunRight(𝐴, 𝑖) 4 runs.push(𝑖, 𝑗); 𝑖 := 𝑗 5 while 𝑖 < 𝑛 6 𝑗 := ExtendRunRight(𝐴, 𝑖) 7 𝑝 := power(runs.top(), (𝑖, 𝑗), 𝑛) 8 while 𝑝 ≤ topmost power 9 merge topmost 2 runs 10 runs.push(𝑖, 𝑗); 𝑖 := 𝑗 11 while runs.size() ≥ 2 12 merge topmost 2 runs a b c d e f 3 run1 run2 24 25 26 27 28 21 22 23 18 19 20 4 5 6 7 8 9 10 11 12 13 14 15 16 17 3 1 2 BEN SMITH WILLIAM CAWLEY GELLING, MARKUS E. NEBEL, AND SEBASTIAN WILD 6 / 16

Slide 29

Slide 29 text

2-WAY POWERSORT 1 procedure Powersort(𝐴[0..𝑛)) 2 𝑖 := 0; runs := new Stack() 3 𝑗 := ExtendRunRight(𝐴, 𝑖) 4 runs.push(𝑖, 𝑗); 𝑖 := 𝑗 5 while 𝑖 < 𝑛 6 𝑗 := ExtendRunRight(𝐴, 𝑖) 7 𝑝 := power(runs.top(), (𝑖, 𝑗), 𝑛) 8 while 𝑝 ≤ topmost power 9 merge topmost 2 runs 10 runs.push(𝑖, 𝑗); 𝑖 := 𝑗 11 while runs.size() ≥ 2 12 merge topmost 2 runs a b c d e f 3 run1 run2 a – 3 run stack 24 25 26 27 28 21 22 23 18 19 20 4 5 6 7 8 9 10 11 12 13 14 15 16 17 3 1 2 BEN SMITH WILLIAM CAWLEY GELLING, MARKUS E. NEBEL, AND SEBASTIAN WILD 6 / 16

Slide 30

Slide 30 text

2-WAY POWERSORT 1 procedure Powersort(𝐴[0..𝑛)) 2 𝑖 := 0; runs := new Stack() 3 𝑗 := ExtendRunRight(𝐴, 𝑖) 4 runs.push(𝑖, 𝑗); 𝑖 := 𝑗 5 while 𝑖 < 𝑛 6 𝑗 := ExtendRunRight(𝐴, 𝑖) 7 𝑝 := power(runs.top(), (𝑖, 𝑗), 𝑛) 8 while 𝑝 ≤ topmost power 9 merge topmost 2 runs 10 runs.push(𝑖, 𝑗); 𝑖 := 𝑗 11 while runs.size() ≥ 2 12 merge topmost 2 runs a b c d e f 3 2 run1 run2 a – 3 run stack 24 25 26 27 28 21 22 23 18 19 20 4 5 6 7 8 9 10 11 12 13 14 15 16 17 3 1 2 BEN SMITH WILLIAM CAWLEY GELLING, MARKUS E. NEBEL, AND SEBASTIAN WILD 6 / 16

Slide 31

Slide 31 text

2-WAY POWERSORT 1 procedure Powersort(𝐴[0..𝑛)) 2 𝑖 := 0; runs := new Stack() 3 𝑗 := ExtendRunRight(𝐴, 𝑖) 4 runs.push(𝑖, 𝑗); 𝑖 := 𝑗 5 while 𝑖 < 𝑛 6 𝑗 := ExtendRunRight(𝐴, 𝑖) 7 𝑝 := power(runs.top(), (𝑖, 𝑗), 𝑛) 8 while 𝑝 ≤ topmost power 9 merge topmost 2 runs 10 runs.push(𝑖, 𝑗); 𝑖 := 𝑗 11 while runs.size() ≥ 2 12 merge topmost 2 runs a b c d e f 3 2 run1 run2 a – 3 b – 2 run stack 24 25 26 27 28 21 22 23 18 19 20 4 5 6 7 8 9 10 11 12 13 14 15 16 17 3 1 2 BEN SMITH WILLIAM CAWLEY GELLING, MARKUS E. NEBEL, AND SEBASTIAN WILD 6 / 16

Slide 32

Slide 32 text

2-WAY POWERSORT 1 procedure Powersort(𝐴[0..𝑛)) 2 𝑖 := 0; runs := new Stack() 3 𝑗 := ExtendRunRight(𝐴, 𝑖) 4 runs.push(𝑖, 𝑗); 𝑖 := 𝑗 5 while 𝑖 < 𝑛 6 𝑗 := ExtendRunRight(𝐴, 𝑖) 7 𝑝 := power(runs.top(), (𝑖, 𝑗), 𝑛) 8 while 𝑝 ≤ topmost power 9 merge topmost 2 runs 10 runs.push(𝑖, 𝑗); 𝑖 := 𝑗 11 while runs.size() ≥ 2 12 merge topmost 2 runs a b c d e f 3 2 run1 run2 a – 3 b – 2 run stack 24 25 26 27 28 21 22 23 18 19 20 4 5 6 7 8 9 10 11 12 13 14 15 16 17 3 1 2 BEN SMITH WILLIAM CAWLEY GELLING, MARKUS E. NEBEL, AND SEBASTIAN WILD 6 / 16

Slide 33

Slide 33 text

2-WAY POWERSORT 1 procedure Powersort(𝐴[0..𝑛)) 2 𝑖 := 0; runs := new Stack() 3 𝑗 := ExtendRunRight(𝐴, 𝑖) 4 runs.push(𝑖, 𝑗); 𝑖 := 𝑗 5 while 𝑖 < 𝑛 6 𝑗 := ExtendRunRight(𝐴, 𝑖) 7 𝑝 := power(runs.top(), (𝑖, 𝑗), 𝑛) 8 while 𝑝 ≤ topmost power 9 merge topmost 2 runs 10 runs.push(𝑖, 𝑗); 𝑖 := 𝑗 11 while runs.size() ≥ 2 12 merge topmost 2 runs a b c d e f 3 2 run1 run2 a – 3 b – 2 run stack merge 24 25 26 27 28 21 22 23 18 19 20 4 5 6 7 8 9 10 11 12 13 14 15 16 17 3 1 2 BEN SMITH WILLIAM CAWLEY GELLING, MARKUS E. NEBEL, AND SEBASTIAN WILD 6 / 16

Slide 34

Slide 34 text

2-WAY POWERSORT 1 procedure Powersort(𝐴[0..𝑛)) 2 𝑖 := 0; runs := new Stack() 3 𝑗 := ExtendRunRight(𝐴, 𝑖) 4 runs.push(𝑖, 𝑗); 𝑖 := 𝑗 5 while 𝑖 < 𝑛 6 𝑗 := ExtendRunRight(𝐴, 𝑖) 7 𝑝 := power(runs.top(), (𝑖, 𝑗), 𝑛) 8 while 𝑝 ≤ topmost power 9 merge topmost 2 runs 10 runs.push(𝑖, 𝑗); 𝑖 := 𝑗 11 while runs.size() ≥ 2 12 merge topmost 2 runs ab c d e f 2 run2 ab – 2 run stack 24 25 26 27 28 21 22 23 18 19 20 4 5 6 7 8 9 10 11 12 13 14 15 16 17 3 1 2 BEN SMITH WILLIAM CAWLEY GELLING, MARKUS E. NEBEL, AND SEBASTIAN WILD 6 / 16

Slide 35

Slide 35 text

2-WAY POWERSORT 1 procedure Powersort(𝐴[0..𝑛)) 2 𝑖 := 0; runs := new Stack() 3 𝑗 := ExtendRunRight(𝐴, 𝑖) 4 runs.push(𝑖, 𝑗); 𝑖 := 𝑗 5 while 𝑖 < 𝑛 6 𝑗 := ExtendRunRight(𝐴, 𝑖) 7 𝑝 := power(runs.top(), (𝑖, 𝑗), 𝑛) 8 while 𝑝 ≤ topmost power 9 merge topmost 2 runs 10 runs.push(𝑖, 𝑗); 𝑖 := 𝑗 11 while runs.size() ≥ 2 12 merge topmost 2 runs ab c d e f 2 1 run1 run2 ab – 2 run stack 24 25 26 27 28 21 22 23 18 19 20 4 5 6 7 8 9 10 11 12 13 14 15 16 17 3 1 2 BEN SMITH WILLIAM CAWLEY GELLING, MARKUS E. NEBEL, AND SEBASTIAN WILD 6 / 16

Slide 36

Slide 36 text

2-WAY POWERSORT 1 procedure Powersort(𝐴[0..𝑛)) 2 𝑖 := 0; runs := new Stack() 3 𝑗 := ExtendRunRight(𝐴, 𝑖) 4 runs.push(𝑖, 𝑗); 𝑖 := 𝑗 5 while 𝑖 < 𝑛 6 𝑗 := ExtendRunRight(𝐴, 𝑖) 7 𝑝 := power(runs.top(), (𝑖, 𝑗), 𝑛) 8 while 𝑝 ≤ topmost power 9 merge topmost 2 runs 10 runs.push(𝑖, 𝑗); 𝑖 := 𝑗 11 while runs.size() ≥ 2 12 merge topmost 2 runs ab c d e f 2 1 run1 run2 ab – 2 c – 1 run stack 24 25 26 27 28 21 22 23 18 19 20 4 5 6 7 8 9 10 11 12 13 14 15 16 17 3 1 2 BEN SMITH WILLIAM CAWLEY GELLING, MARKUS E. NEBEL, AND SEBASTIAN WILD 6 / 16

Slide 37

Slide 37 text

2-WAY POWERSORT 1 procedure Powersort(𝐴[0..𝑛)) 2 𝑖 := 0; runs := new Stack() 3 𝑗 := ExtendRunRight(𝐴, 𝑖) 4 runs.push(𝑖, 𝑗); 𝑖 := 𝑗 5 while 𝑖 < 𝑛 6 𝑗 := ExtendRunRight(𝐴, 𝑖) 7 𝑝 := power(runs.top(), (𝑖, 𝑗), 𝑛) 8 while 𝑝 ≤ topmost power 9 merge topmost 2 runs 10 runs.push(𝑖, 𝑗); 𝑖 := 𝑗 11 while runs.size() ≥ 2 12 merge topmost 2 runs ab c d e f 2 1 run1 run2 ab – 2 c – 1 run stack 24 25 26 27 28 21 22 23 18 19 20 4 5 6 7 8 9 10 11 12 13 14 15 16 17 3 1 2 BEN SMITH WILLIAM CAWLEY GELLING, MARKUS E. NEBEL, AND SEBASTIAN WILD 6 / 16

Slide 38

Slide 38 text

2-WAY POWERSORT 1 procedure Powersort(𝐴[0..𝑛)) 2 𝑖 := 0; runs := new Stack() 3 𝑗 := ExtendRunRight(𝐴, 𝑖) 4 runs.push(𝑖, 𝑗); 𝑖 := 𝑗 5 while 𝑖 < 𝑛 6 𝑗 := ExtendRunRight(𝐴, 𝑖) 7 𝑝 := power(runs.top(), (𝑖, 𝑗), 𝑛) 8 while 𝑝 ≤ topmost power 9 merge topmost 2 runs 10 runs.push(𝑖, 𝑗); 𝑖 := 𝑗 11 while runs.size() ≥ 2 12 merge topmost 2 runs ab c d e f 2 1 run1 run2 ab – 2 c – 1 run stack merge 24 25 26 27 28 21 22 23 18 19 20 4 5 6 7 8 9 10 11 12 13 14 15 16 17 3 1 2 BEN SMITH WILLIAM CAWLEY GELLING, MARKUS E. NEBEL, AND SEBASTIAN WILD 6 / 16

Slide 39

Slide 39 text

2-WAY POWERSORT 1 procedure Powersort(𝐴[0..𝑛)) 2 𝑖 := 0; runs := new Stack() 3 𝑗 := ExtendRunRight(𝐴, 𝑖) 4 runs.push(𝑖, 𝑗); 𝑖 := 𝑗 5 while 𝑖 < 𝑛 6 𝑗 := ExtendRunRight(𝐴, 𝑖) 7 𝑝 := power(runs.top(), (𝑖, 𝑗), 𝑛) 8 while 𝑝 ≤ topmost power 9 merge topmost 2 runs 10 runs.push(𝑖, 𝑗); 𝑖 := 𝑗 11 while runs.size() ≥ 2 12 merge topmost 2 runs abc d e f 1 run2 abc – 1 run stack 24 25 26 27 28 21 22 23 18 19 20 4 5 6 7 8 9 10 11 12 13 14 15 16 17 3 1 2 BEN SMITH WILLIAM CAWLEY GELLING, MARKUS E. NEBEL, AND SEBASTIAN WILD 6 / 16

Slide 40

Slide 40 text

2-WAY POWERSORT 1 procedure Powersort(𝐴[0..𝑛)) 2 𝑖 := 0; runs := new Stack() 3 𝑗 := ExtendRunRight(𝐴, 𝑖) 4 runs.push(𝑖, 𝑗); 𝑖 := 𝑗 5 while 𝑖 < 𝑛 6 𝑗 := ExtendRunRight(𝐴, 𝑖) 7 𝑝 := power(runs.top(), (𝑖, 𝑗), 𝑛) 8 while 𝑝 ≤ topmost power 9 merge topmost 2 runs 10 runs.push(𝑖, 𝑗); 𝑖 := 𝑗 11 while runs.size() ≥ 2 12 merge topmost 2 runs abc d e f 1 2 run1 run2 abc – 1 run stack 24 25 26 27 28 21 22 23 18 19 20 4 5 6 7 8 9 10 11 12 13 14 15 16 17 3 1 2 BEN SMITH WILLIAM CAWLEY GELLING, MARKUS E. NEBEL, AND SEBASTIAN WILD 6 / 16

Slide 41

Slide 41 text

2-WAY POWERSORT 1 procedure Powersort(𝐴[0..𝑛)) 2 𝑖 := 0; runs := new Stack() 3 𝑗 := ExtendRunRight(𝐴, 𝑖) 4 runs.push(𝑖, 𝑗); 𝑖 := 𝑗 5 while 𝑖 < 𝑛 6 𝑗 := ExtendRunRight(𝐴, 𝑖) 7 𝑝 := power(runs.top(), (𝑖, 𝑗), 𝑛) 8 while 𝑝 ≤ topmost power 9 merge topmost 2 runs 10 runs.push(𝑖, 𝑗); 𝑖 := 𝑗 11 while runs.size() ≥ 2 12 merge topmost 2 runs abc d e f 1 2 run1 run2 abc – 1 d – 2 run stack 24 25 26 27 28 21 22 23 18 19 20 4 5 6 7 8 9 10 11 12 13 14 15 16 17 3 1 2 BEN SMITH WILLIAM CAWLEY GELLING, MARKUS E. NEBEL, AND SEBASTIAN WILD 6 / 16

Slide 42

Slide 42 text

2-WAY POWERSORT 1 procedure Powersort(𝐴[0..𝑛)) 2 𝑖 := 0; runs := new Stack() 3 𝑗 := ExtendRunRight(𝐴, 𝑖) 4 runs.push(𝑖, 𝑗); 𝑖 := 𝑗 5 while 𝑖 < 𝑛 6 𝑗 := ExtendRunRight(𝐴, 𝑖) 7 𝑝 := power(runs.top(), (𝑖, 𝑗), 𝑛) 8 while 𝑝 ≤ topmost power 9 merge topmost 2 runs 10 runs.push(𝑖, 𝑗); 𝑖 := 𝑗 11 while runs.size() ≥ 2 12 merge topmost 2 runs abc d e f 1 2 4 run1 run2 abc – 1 d – 2 run stack 24 25 26 27 28 21 22 23 18 19 20 4 5 6 7 8 9 10 11 12 13 14 15 16 17 3 1 2 BEN SMITH WILLIAM CAWLEY GELLING, MARKUS E. NEBEL, AND SEBASTIAN WILD 6 / 16

Slide 43

Slide 43 text

2-WAY POWERSORT 1 procedure Powersort(𝐴[0..𝑛)) 2 𝑖 := 0; runs := new Stack() 3 𝑗 := ExtendRunRight(𝐴, 𝑖) 4 runs.push(𝑖, 𝑗); 𝑖 := 𝑗 5 while 𝑖 < 𝑛 6 𝑗 := ExtendRunRight(𝐴, 𝑖) 7 𝑝 := power(runs.top(), (𝑖, 𝑗), 𝑛) 8 while 𝑝 ≤ topmost power 9 merge topmost 2 runs 10 runs.push(𝑖, 𝑗); 𝑖 := 𝑗 11 while runs.size() ≥ 2 12 merge topmost 2 runs abc d e f 1 2 4 run1 run2 abc – 1 d – 2 e – 4 run stack 24 25 26 27 28 21 22 23 18 19 20 4 5 6 7 8 9 10 11 12 13 14 15 16 17 3 1 2 BEN SMITH WILLIAM CAWLEY GELLING, MARKUS E. NEBEL, AND SEBASTIAN WILD 6 / 16

Slide 44

Slide 44 text

2-WAY POWERSORT 1 procedure Powersort(𝐴[0..𝑛)) 2 𝑖 := 0; runs := new Stack() 3 𝑗 := ExtendRunRight(𝐴, 𝑖) 4 runs.push(𝑖, 𝑗); 𝑖 := 𝑗 5 while 𝑖 < 𝑛 6 𝑗 := ExtendRunRight(𝐴, 𝑖) 7 𝑝 := power(runs.top(), (𝑖, 𝑗), 𝑛) 8 while 𝑝 ≤ topmost power 9 merge topmost 2 runs 10 runs.push(𝑖, 𝑗); 𝑖 := 𝑗 11 while runs.size() ≥ 2 12 merge topmost 2 runs abc d e f 1 2 4 abc – 1 d – 2 e – 4 run stack 24 25 26 27 28 21 22 23 18 19 20 4 5 6 7 8 9 10 11 12 13 14 15 16 17 3 1 2 BEN SMITH WILLIAM CAWLEY GELLING, MARKUS E. NEBEL, AND SEBASTIAN WILD 6 / 16

Slide 45

Slide 45 text

2-WAY POWERSORT 1 procedure Powersort(𝐴[0..𝑛)) 2 𝑖 := 0; runs := new Stack() 3 𝑗 := ExtendRunRight(𝐴, 𝑖) 4 runs.push(𝑖, 𝑗); 𝑖 := 𝑗 5 while 𝑖 < 𝑛 6 𝑗 := ExtendRunRight(𝐴, 𝑖) 7 𝑝 := power(runs.top(), (𝑖, 𝑗), 𝑛) 8 while 𝑝 ≤ topmost power 9 merge topmost 2 runs 10 runs.push(𝑖, 𝑗); 𝑖 := 𝑗 11 while runs.size() ≥ 2 12 merge topmost 2 runs merge-down phase abc d e f 1 2 4 abc – 1 d – 2 e – 4 run stack 24 25 26 27 28 21 22 23 18 19 20 4 5 6 7 8 9 10 11 12 13 14 15 16 17 3 1 2 BEN SMITH WILLIAM CAWLEY GELLING, MARKUS E. NEBEL, AND SEBASTIAN WILD 6 / 16

Slide 46

Slide 46 text

2-WAY POWERSORT 1 procedure Powersort(𝐴[0..𝑛)) 2 𝑖 := 0; runs := new Stack() 3 𝑗 := ExtendRunRight(𝐴, 𝑖) 4 runs.push(𝑖, 𝑗); 𝑖 := 𝑗 5 while 𝑖 < 𝑛 6 𝑗 := ExtendRunRight(𝐴, 𝑖) 7 𝑝 := power(runs.top(), (𝑖, 𝑗), 𝑛) 8 while 𝑝 ≤ topmost power 9 merge topmost 2 runs 10 runs.push(𝑖, 𝑗); 𝑖 := 𝑗 11 while runs.size() ≥ 2 12 merge topmost 2 runs merge-down phase abc d e f 1 2 4 abc – 1 d – 2 e – 4 run stack merge 24 25 26 27 28 21 22 23 18 19 20 4 5 6 7 8 9 10 11 12 13 14 15 16 17 3 1 2 BEN SMITH WILLIAM CAWLEY GELLING, MARKUS E. NEBEL, AND SEBASTIAN WILD 6 / 16

Slide 47

Slide 47 text

2-WAY POWERSORT 1 procedure Powersort(𝐴[0..𝑛)) 2 𝑖 := 0; runs := new Stack() 3 𝑗 := ExtendRunRight(𝐴, 𝑖) 4 runs.push(𝑖, 𝑗); 𝑖 := 𝑗 5 while 𝑖 < 𝑛 6 𝑗 := ExtendRunRight(𝐴, 𝑖) 7 𝑝 := power(runs.top(), (𝑖, 𝑗), 𝑛) 8 while 𝑝 ≤ topmost power 9 merge topmost 2 runs 10 runs.push(𝑖, 𝑗); 𝑖 := 𝑗 11 while runs.size() ≥ 2 12 merge topmost 2 runs merge-down phase abc d ef 1 2 abc – 1 d – 2 run stack 24 25 26 27 28 21 22 23 18 19 20 4 5 6 7 8 9 10 11 12 13 14 15 16 17 3 1 2 BEN SMITH WILLIAM CAWLEY GELLING, MARKUS E. NEBEL, AND SEBASTIAN WILD 6 / 16

Slide 48

Slide 48 text

2-WAY POWERSORT 1 procedure Powersort(𝐴[0..𝑛)) 2 𝑖 := 0; runs := new Stack() 3 𝑗 := ExtendRunRight(𝐴, 𝑖) 4 runs.push(𝑖, 𝑗); 𝑖 := 𝑗 5 while 𝑖 < 𝑛 6 𝑗 := ExtendRunRight(𝐴, 𝑖) 7 𝑝 := power(runs.top(), (𝑖, 𝑗), 𝑛) 8 while 𝑝 ≤ topmost power 9 merge topmost 2 runs 10 runs.push(𝑖, 𝑗); 𝑖 := 𝑗 11 while runs.size() ≥ 2 12 merge topmost 2 runs merge-down phase abc d ef 1 2 abc – 1 d – 2 run stack merge 24 25 26 27 28 21 22 23 18 19 20 4 5 6 7 8 9 10 11 12 13 14 15 16 17 3 1 2 BEN SMITH WILLIAM CAWLEY GELLING, MARKUS E. NEBEL, AND SEBASTIAN WILD 6 / 16

Slide 49

Slide 49 text

2-WAY POWERSORT 1 procedure Powersort(𝐴[0..𝑛)) 2 𝑖 := 0; runs := new Stack() 3 𝑗 := ExtendRunRight(𝐴, 𝑖) 4 runs.push(𝑖, 𝑗); 𝑖 := 𝑗 5 while 𝑖 < 𝑛 6 𝑗 := ExtendRunRight(𝐴, 𝑖) 7 𝑝 := power(runs.top(), (𝑖, 𝑗), 𝑛) 8 while 𝑝 ≤ topmost power 9 merge topmost 2 runs 10 runs.push(𝑖, 𝑗); 𝑖 := 𝑗 11 while runs.size() ≥ 2 12 merge topmost 2 runs merge-down phase abc def 1 abc – 1 run stack 24 25 26 27 28 21 22 23 18 19 20 4 5 6 7 8 9 10 11 12 13 14 15 16 17 3 1 2 BEN SMITH WILLIAM CAWLEY GELLING, MARKUS E. NEBEL, AND SEBASTIAN WILD 6 / 16

Slide 50

Slide 50 text

2-WAY POWERSORT 1 procedure Powersort(𝐴[0..𝑛)) 2 𝑖 := 0; runs := new Stack() 3 𝑗 := ExtendRunRight(𝐴, 𝑖) 4 runs.push(𝑖, 𝑗); 𝑖 := 𝑗 5 while 𝑖 < 𝑛 6 𝑗 := ExtendRunRight(𝐴, 𝑖) 7 𝑝 := power(runs.top(), (𝑖, 𝑗), 𝑛) 8 while 𝑝 ≤ topmost power 9 merge topmost 2 runs 10 runs.push(𝑖, 𝑗); 𝑖 := 𝑗 11 while runs.size() ≥ 2 12 merge topmost 2 runs merge-down phase abc def 1 abc – 1 run stack merge 24 25 26 27 28 21 22 23 18 19 20 4 5 6 7 8 9 10 11 12 13 14 15 16 17 3 1 2 BEN SMITH WILLIAM CAWLEY GELLING, MARKUS E. NEBEL, AND SEBASTIAN WILD 6 / 16

Slide 51

Slide 51 text

2-WAY POWERSORT 1 procedure Powersort(𝐴[0..𝑛)) 2 𝑖 := 0; runs := new Stack() 3 𝑗 := ExtendRunRight(𝐴, 𝑖) 4 runs.push(𝑖, 𝑗); 𝑖 := 𝑗 5 while 𝑖 < 𝑛 6 𝑗 := ExtendRunRight(𝐴, 𝑖) 7 𝑝 := power(runs.top(), (𝑖, 𝑗), 𝑛) 8 while 𝑝 ≤ topmost power 9 merge topmost 2 runs 10 runs.push(𝑖, 𝑗); 𝑖 := 𝑗 11 while runs.size() ≥ 2 12 merge topmost 2 runs abcdef 24 25 26 27 28 21 22 23 18 19 20 4 5 6 7 8 9 10 11 12 13 14 15 16 17 3 1 2 BEN SMITH WILLIAM CAWLEY GELLING, MARKUS E. NEBEL, AND SEBASTIAN WILD 6 / 16

Slide 52

Slide 52 text

WHY MERGE MULTI-WAY? ▶ Memory transfer costs have become a tighter bottleneck than Processor costs in various sorting algorithms (Kushagra et.al., 2014) • But it’s a close run thing! ▶ To reduce these costs, take inspiration from external memory techniques/algorithms • Specifically, k-way merging ▶ Tuning is important: • Low k reduces Processor costs and is easy to implement • High k reduces Memory costs (I/Os) but is harder to implement • Optimal value depends on data type, hardware, language,.. . BEN SMITH WILLIAM CAWLEY GELLING, MARKUS E. NEBEL, AND SEBASTIAN WILD 7 / 16

Slide 53

Slide 53 text

4 WAY MERGING 3 4 5 2 1 3 2 4 3 44 45 46 47 48 49 50 41 42 43 40 39 33 34 35 36 37 38 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 11 12 13 14 15 16 10 7 8 9 1 2 3 4 5 6 5 4 5 3 5 4 5 2 5 4 5 3 5 4 5 1 5 4 5 3 5 4 5 2 5 4 5 3 5 4 5 BEN SMITH WILLIAM CAWLEY GELLING, MARKUS E. NEBEL, AND SEBASTIAN WILD 8 / 16

Slide 54

Slide 54 text

4 WAY MERGING 3 4 5 2 1 3 2 4 3 44 45 46 47 48 49 50 41 42 43 40 39 33 34 35 36 37 38 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 11 12 13 14 15 16 10 7 8 9 1 2 3 4 5 6 5 4 5 3 5 4 5 2 5 4 5 3 5 4 5 1 5 4 5 3 5 4 5 2 5 4 5 3 5 4 5 2 2 3 1 1 2 1 2 2 44 45 46 47 48 49 50 41 42 43 40 39 33 34 35 36 37 38 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 11 12 13 14 15 16 10 7 8 9 1 2 3 4 5 6 3 3 3 2 3 3 3 2 3 3 3 2 3 3 3 1 3 3 3 2 3 3 3 2 3 3 3 2 3 3 3 1 3 3 3 2 3 3 3 2 3 3 3 2 3 3 3 1 3 3 3 2 3 3 3 2 3 3 3 2 3 3 3 BEN SMITH WILLIAM CAWLEY GELLING, MARKUS E. NEBEL, AND SEBASTIAN WILD 8 / 16

Slide 55

Slide 55 text

MULTIWAY MERGING ▶ New possibility: can now have multiple merges on the stack with the same power ▶ Handle but using a multi-way merge ▶ Specifically, a Winner tree, using sentinels wherever possible BEN SMITH WILLIAM CAWLEY GELLING, MARKUS E. NEBEL, AND SEBASTIAN WILD 9 / 16

Slide 56

Slide 56 text

RESULTS 1: RUNS OF EXPECTED LENGTH √ n, I N TS 4 5 6 7 8 1.4 1.6 1.8 2.0 2.2 running time (int, random runs) 4-way Powersort 4-way Powersort (no sentinels) 2-way Powersort 2-way Powersort (no sentinels) 2-way Powersort (buffer smaller run only) std::sort std::stable_sort top-down mergesort ▶ Normalized running times against log10 (n). 320 340 360 380 400 running time (107 ints, random runs) 4-way Powersort 4-way Powersort (no sentinels) 2-way Powersort 2-way Powersort (no sentinels) 2-way Powersort (buffer smaller run only) ▶ Distributions of running time in ms for the same data BEN SMITH WILLIAM CAWLEY GELLING, MARKUS E. NEBEL, AND SEBASTIAN WILD 10 / 16

Slide 57

Slide 57 text

RESULTS 2: RUNS OF EXPECTED LENGTH √ n, L O N G + POINTER 4 5 6 7 8 1.5 2.0 2.5 3.0 running time (long+pointer, random runs) 4-way Powersort 4-way Powersort (no sentinels) 2-way Powersort 2-way Powersort (no sentinels) 2-way Powersort (buffer smaller run only) std::sort std::stable_sort top-down mergesort ▶ Normalized running times against log10 (n). 400 450 500 550 running time (107 long+ptr, random runs) 4-way Powersort 4-way Powersort (no sentinels) 2-way Powersort 2-way Powersort (no sentinels) 2-way Powersort (buffer smaller run only) ▶ Distributions of running time in ms for the same data BEN SMITH WILLIAM CAWLEY GELLING, MARKUS E. NEBEL, AND SEBASTIAN WILD 11 / 16

Slide 58

Slide 58 text

RESULTS 3: RANDOM PERMUTATIONS, I N TS 4 5 6 7 8 2.8 3.0 3.2 3.4 running time (int, rand. perm.) 4-way Powersort 4-way Powersort (no sentinels) 2-way Powersort 2-way Powersort (no sentinels) 2-way Powersort (buffer smaller run only) std::sort std::stable_sort top-down mergesort ▶ Normalized (time / n lg n) running times against log10 (n). ▶ note that std::sort in C++ is intro sort – not a stable method BEN SMITH WILLIAM CAWLEY GELLING, MARKUS E. NEBEL, AND SEBASTIAN WILD 12 / 16

Slide 59

Slide 59 text

RESULTS 4: RUNS OF EXPECTED LENGTH √ n, I N TS 4 5 6 7 8 0.5 1.0 1.5 2.0 2.5 3.0 3.5 scanned elements (int, random runs) 4-way Powersort 2-way Powersort (buffer smaller run only) 2-way Powersort top-down mergesort ▶ Normalized merge cost against log10 (n). BEN SMITH WILLIAM CAWLEY GELLING, MARKUS E. NEBEL, AND SEBASTIAN WILD 13 / 16

Slide 60

Slide 60 text

CONCLUSION ▶ Findings • 4-way Powersort can yield significant performance improvements • This can be explained by its reduced merge cost • Some of these results rely on the use of sentinels BEN SMITH WILLIAM CAWLEY GELLING, MARKUS E. NEBEL, AND SEBASTIAN WILD 14 / 16

Slide 61

Slide 61 text

CONCLUSION ▶ Findings • 4-way Powersort can yield significant performance improvements • This can be explained by its reduced merge cost • Some of these results rely on the use of sentinels ▶ Further Work • Fast multi-way merging without simple sentinels • Study multi-way powersort in a wider technological context • Compare multi-way powersort with more competitors, specifically multiway quicksort variants. BEN SMITH WILLIAM CAWLEY GELLING, MARKUS E. NEBEL, AND SEBASTIAN WILD 14 / 16

Slide 62

Slide 62 text

CONCLUSION ▶ Findings • 4-way Powersort can yield significant performance improvements • This can be explained by its reduced merge cost • Some of these results rely on the use of sentinels ▶ Further Work • Fast multi-way merging without simple sentinels • Study multi-way powersort in a wider technological context • Compare multi-way powersort with more competitors, specifically multiway quicksort variants. ▶ Recommendations • Users of Timsort should seriously consider the Powersort merge policy • Users of Timsort and 2-way powersort may wish to consider multi-way Powersort ▶ Particularly where comparisons are cheap and sentinels are useable BEN SMITH WILLIAM CAWLEY GELLING, MARKUS E. NEBEL, AND SEBASTIAN WILD 14 / 16

Slide 63

Slide 63 text

THANKS FOR LISTENING! BEN SMITH WILLIAM CAWLEY GELLING, MARKUS E. NEBEL, AND SEBASTIAN WILD 15 / 16

Slide 64

Slide 64 text

RESULTS 5: TIME AS FUNCTION OF PRESORTEDNESS BEN SMITH WILLIAM CAWLEY GELLING, MARKUS E. NEBEL, AND SEBASTIAN WILD 16 / 16