Sort a two dimensional mesh by alternating row sorts and column sorts until the grid is globally ordered.
Shear sort is a parallel sorting algorithm for data arranged on a two dimensional mesh. It alternates between sorting rows and sorting columns. Rows are sorted in a snake like order: even rows left to right, odd rows right to left. Columns are sorted top to bottom.
This alternating pattern gradually moves small values toward the beginning of the snake order and large values toward the end.
Problem
Given an grid of values, sort all values according to snake order.
Snake order means:
row 0: left to right
row 1: right to left
row 2: left to right
row 3: right to left
...Algorithm
shear_sort(G):
repeat O(log(r * c)) times:
parallel for each row:
if row index is even:
sort row ascending
else:
sort row descending
parallel for each column:
sort column ascending
final row sort in snake orderThe row phase orders values within each horizontal line. The column phase moves smaller values upward and larger values downward.
Example
For a grid, snake order reads:
G[0][0], G[0][1], G[0][2], G[0][3],
G[1][3], G[1][2], G[1][1], G[1][0],
G[2][0], G[2][1], G[2][2], G[2][3]The final grid is sorted when reading values in this order.
Complexity
Let .
| measure | value |
|---|---|
| phases | |
| row sort work | row sorts of length |
| column sort work | column sorts of length |
| total work | depends on row and column sort method |
| parallel structure | rows and columns sort independently |
With comparison sorting for rows and columns, the total work is commonly written as:
depending on the precise mesh model and local sort implementation.
Correctness
The snake row ordering gives the two dimensional grid a one dimensional total order. Row sorting reduces disorder within rows. Column sorting moves smaller elements toward earlier rows and larger elements toward later rows. Repeating these phases decreases global disorder until every row and column is consistent with snake order.
After enough phases, the final row sort produces a grid whose snake traversal is globally sorted.
Practical Considerations
- Designed for mesh connected parallel machines.
- Uses regular communication patterns.
- Rows and columns can be processed in parallel.
- Performs more work than practical general purpose sorts.
- Useful for teaching parallel sorting on processor meshes.
- The snake order avoids discontinuity between adjacent rows.
When to Use
Use shear sort when:
- data is naturally arranged on a two dimensional mesh
- communication is cheaper along rows and columns
- regular local synchronization is desired
- studying parallel sorting networks or mesh algorithms
Avoid it for ordinary CPU sorting. Merge sort, quicksort, radix sort, and sample sort are usually more practical.
Implementation
def shear_sort(grid, rounds=None):
rows = len(grid)
cols = len(grid[0])
n = rows * cols
if rounds is None:
rounds = n.bit_length()
for _ in range(rounds):
for r in range(rows):
grid[r].sort(reverse=(r % 2 == 1))
for c in range(cols):
col = [grid[r][c] for r in range(rows)]
col.sort()
for r in range(rows):
grid[r][c] = col[r]
for r in range(rows):
grid[r].sort(reverse=(r % 2 == 1))
return gridfunc ShearSort(grid [][]int) {
rows := len(grid)
if rows == 0 {
return
}
cols := len(grid[0])
n := rows * cols
rounds := bits.Len(uint(n))
for round := 0; round < rounds; round++ {
for r := 0; r < rows; r++ {
sort.Ints(grid[r])
if r%2 == 1 {
reverse(grid[r])
}
}
for c := 0; c < cols; c++ {
col := make([]int, rows)
for r := 0; r < rows; r++ {
col[r] = grid[r][c]
}
sort.Ints(col)
for r := 0; r < rows; r++ {
grid[r][c] = col[r]
}
}
}
for r := 0; r < rows; r++ {
sort.Ints(grid[r])
if r%2 == 1 {
reverse(grid[r])
}
}
}
func reverse(a []int) {
for i, j := 0, len(a)-1; i < j; i, j = i+1, j-1 {
a[i], a[j] = a[j], a[i]
}
}