diff --git a/benchmarks/mem/quickselect.bril b/benchmarks/mem/quickselect.bril new file mode 100644 index 000000000..0ed7c960c --- /dev/null +++ b/benchmarks/mem/quickselect.bril @@ -0,0 +1,123 @@ +# Quick select algorithm +# Inputs: An unordered array of 6 elements and a number k +# Output: kth smallest number in the array +# Adopted pack and print_array code from bubblesort by Jiajie Li + +@pack(size: int, n1: int, n2: int, n3: int, n4: int, n5: int, n6: int) : ptr { + one: int = const 1; + i: int = const 0; + array: ptr = alloc size; +# Pack data into array manually. Cannot use loop because of the different var name. + loc: ptr = ptradd array i; + store loc n1; + i: int = add i one; + loc: ptr = ptradd array i; + store loc n2; + i: int = add i one; + loc: ptr = ptradd array i; + store loc n3; + i: int = add i one; + loc: ptr = ptradd array i; + store loc n4; + i: int = add i one; + loc: ptr = ptradd array i; + store loc n5; + i: int = add i one; + loc: ptr = ptradd array i; + store loc n6; + ret array; +} + +@print_array(array: ptr, size: int) { + i: int = const 0; + one: int = const 1; +.loop: + cond: bool = lt i size; + br cond .body .done; +.body: + loc: ptr = ptradd array i; + val: int = load loc; + print val; +.loop_end: + i: int = add i one; + jmp .loop; +.done: + ret; +} + + +@partition(array: ptr, l: int, r: int): int { + one: int = const 1; + pivotloc: ptr = ptradd array r; + pivot: int = load pivotloc; + i: int = id l; + j: int = id l; +.loop: + cond: bool = lt j r; + br cond .body .done; +.body: + curloc: ptr = ptradd array j; + cur: int = load curloc; + swap: bool = le cur pivot; + br swap .swap_j .loop_end; +.swap_j: + iloc: ptr = ptradd array i; + ival: int = load iloc; + store curloc ival; + store iloc cur; + i: int = add i one; +.loop_end: + j: int = add j one; + jmp .loop; +.done: + iloc: ptr = ptradd array i; + ival: int = load iloc; + store iloc pivot; + store pivotloc ival; + ret i; +} + +@quickselect(array: ptr, l: int, r: int, k: int): int { + one: int = const 1; + index: int = call @partition array l r; + ipos: int = sub index l; + kpos: int = sub k one; + ieqk: bool = eq ipos kpos; + br ieqk .found .not_found; +.found: + iloc: ptr = ptradd array index; + i: int = load iloc; + ret i; +.not_found: + igtk: bool = gt ipos kpos; + br igtk .greater .less; +.greater: + newr: int = sub index one; + i: int = call @quickselect array l newr k; + ret i; +.less: + newl: int = add index one; + newk: int = sub k index; + newk: int = add newk l; + newk: int = sub newk one; + i: int = call @quickselect array newl r newk; + ret i; +} + +@main() { + k: int = const 4; + n1: int = const 97; + n2: int = const 108; + n3: int = const 98; + n4: int = const 101; + n5: int = const 114; + n6: int = const 116; + + zero: int = const 0; + five: int = const 5; + size: int = const 6; + array: ptr = call @pack size n1 n2 n3 n4 n5 n6; + output: int = call @quickselect array zero five k; + print output; + free array; +} \ No newline at end of file diff --git a/benchmarks/mem/quickselect.out b/benchmarks/mem/quickselect.out new file mode 100644 index 000000000..3b20426c0 --- /dev/null +++ b/benchmarks/mem/quickselect.out @@ -0,0 +1 @@ +108 diff --git a/benchmarks/mem/quickselect.prof b/benchmarks/mem/quickselect.prof new file mode 100644 index 000000000..5a4de8331 --- /dev/null +++ b/benchmarks/mem/quickselect.prof @@ -0,0 +1 @@ +total_dyn_inst: 279 diff --git a/docs/tools/bench.md b/docs/tools/bench.md index 6067210d3..6427391c5 100644 --- a/docs/tools/bench.md +++ b/docs/tools/bench.md @@ -55,6 +55,7 @@ The current benchmarks are: * `primitive-root`: Computes a [primitive root][primitive_root] modulo a prime number input. * `pythagorean_triple`: Prints all Pythagorean triples with the given c, if such triples exist. An intentionally very naive implementation. * `quadratic`: The [quadratic formula][qf], including a hand-rolled implementation of square root. +* `quickselect`: Find the kth smallest element in an array using the quickselect algorithm. * `quicksort`: [Quicksort using the Lomuto partition scheme][qsort]. * `quicksort-hoare`: Quicksort using [Hoare partioning][qsort-hoare] and median of three pivot selection. * `recfact`: Compute *n!* using recursive function calls.