Bitonic Sort algorithm used on Nvidia GPUs
Bitonic Sort algorithm used on Nvidia GPUs
Parallel Programming
John Mellor-Crummey
Department of Computer Science, Rice University
[email protected]
https://wiki.rice.edu/confluence/display/PARPROG/COMP322
2
Sorting Network
y ⊕ max(x,y)
– decreasing (denoted Ө) : x' = max(x,y) and y' = min(x,y)
x Ө max(x,y)
y Ө min(x,y)
• Sorting network speed is proportional to its depth
3
Sorting Networks
4
Example: Bitonic Sorting Network
• Bitonic sequence
—two parts: increasing and decreasing
– 〈1,2,4,7,6,0〉: first increases and then decreases (or vice versa)
—cyclic rotation of a bitonic sequence is also considered bitonic
– 〈8,9,2,1,0,4〉: cyclic rotation of 〈0,4,8,9,2,1〉
5
Bitonic Split (Batcher, 1968)
• Sequence properties
—s1 and s2 are both bitonic
—∀x ∀y x ∈ s1, y ∈ s2 , x < y
min max 7
Splitting Bitonic Sequences - I
Sequence properties
s1 and s2 are both bitonic
∀x ∀y x ∈ s1, y ∈ s2 , x < y
min max 8
Splitting Bitonic Sequences - I
Sequence properties
s1 and s2 are both bitonic
∀x ∀y x ∈ s1, y ∈ s2 , x < y
min max 9
Splitting Bitonic Sequences - I
Sequence properties
s1 and s2 are both bitonic
∀x ∀y x ∈ s1, y ∈ s2 , x < y
min max 10
Splitting Bitonic Sequences - I
Sequence properties
s1 and s2 are both bitonic
∀x ∀y x ∈ s1, y ∈ s2 , x < y
min max 11
Splitting Bitonic Sequences - II
Sequence properties
s1 and s2 are both bitonic
∀x ∀y x ∈ s1, y ∈ s2 , x < y
min max 12
Bitonic Merge
13
Sorting via Bitonic Merging Network
14
Bitonic Merging Network, ⊕ BM[16]
16
Building a Bitonic Sequence
17
Building a Bitonic Sequence
20
From Sorting Network to Pseudocode
21
Bitonic Sort in HJ
void bmerge(final int[] A, final int low, final int high, boolean asc) {
if ( high-low > 1 ) {
final int mid = (low + high)/2 ;
final int size = high – low + 1;
forall (point[i]:[low:mid]) orderElementPair(A, i, i+size/2, asc);
finish {
async bmerge(A, low, mid, asc); async bmerge(A, mid+1, high, asc);
} // finish
} // if
} // bmerge
void bsort (final int[] A, final int low, final int high, boolean asc) {
if ( high-low > 1 ) {
finish {
final int mid = (low + high)/2 ;
async bsort(A, low, mid, asc); async bsort(A, mid+1, high, !asc);
} // finish
bmerge(A, low, high, asc); // asc = true is for ascending order
} // if
} // sort
22
Batcher’s Bitonic Sort in NESL
function bitonic_merge(a) =
if (#a == 1) then a
else
let
halves = bottop(a)
mins = {min(x, y) : x in halves[0]; y in halves[1]};
maxs = {max(x, y) : x in halves[0]; y in halves[1]};
in flatten({bitonic_merge(x) : x in [mins,maxs]});
function bitonic_sort(a) =
if (#a == 1) then a
else
let b = {bitonic_sort(x) : x in bottop(a)};
in bitonic_merge(b[0]++reverse(b[1]));
24