#include #include #include #define BUCKETS 0b1000 #define BUCKET_SIZE 20 #define LENGTH 32 int count = 0; bool LT(int a, int b) { count++; return a < b; } // TODO: parallellize rotate-left instruction (BSL) // This can be done by partially unrolling the loop ;) // Bucket/Insertion sort (except final merge). C-style pseudocode void bi_sort(short *data){ short *buckets; short pc_, ir_, ar, gr, hr, lc_, ir_; for(pc_ = 0xE0; pc_ != 0; ++pc_){ // Fetch and hash ar = data[pc_]; gr = data[pc_]; ar = ar >> 9; ar = ar & 0b1111000; hr = ar; ar = buckets[ar]; // Index 0 is pointer to end of array ++ar; buckets[hr] = ar; // Increment pointer (since we're inserting a new value) --ar; ir_ = pc_; // Push pc pc_ = ar; // Copy start index to pc (for fast indexing) ar = ar - hr; // Compute length lc_ = ar; // Loop AR-times --lc_; while(lc_ != 0){ ++pc_; ar = data[pc_]; if((ar -= gr) < 0){ ar += gr; data[pc_] = gr; // Insert here while(lc_ != 0){ ++pc_; gr = data[pc_]; data[pc_] = ar; ar = gr; --lc_; } goto END; } --lc_; } ++pc_; data[pc_] = gr; // GR was the biggest. Insert it at the end END: pc_ = ir_; // Pop pc } } void sort(short *data, int length) { short buckets[BUCKETS][BUCKET_SIZE] = {}; short a_, pc, c, d; // Bucketsort for (a_ = 0; a_ < length; a_++) { c = data[a_]; d = (c >> 13) & 0b111; pc = buckets[d][0]; pc++; buckets[d][0] = pc; buckets[d][pc] = c; } for (short q = 0; q < BUCKETS; q++) { short *curr = buckets[q]; int length = curr[0]; printf("buck: %d\tlength: %hd\n", q, curr[0]); for (short i = 0; i < length; i++) { printf("%hd, ", curr[i + 1]); } printf("\n"); } #if 0 i ← 1 while i < length(A) x ← A[i] j ← i - 1 while j >= 0 and A[j] > x A[j+1] ← A[j] j ← j - 1 end while A[j+1] ← x i ← i + 1 end while #endif // Insertion Sort for (short q = 0; q < BUCKETS; q++) { short length = buckets[q][0]; short *curr = buckets[q] + 1; a_ = 1; while (a_ < length) { c = curr[a_]; pc = a_ - 1; while (pc >= 0 && LT(curr[pc], c)) { curr[pc+1] = curr[pc]; pc--; } curr[pc+1] = c; a_++; } } // Merge the buckets pc = 0; int h = 0b100; for (short q = 0; q < BUCKETS; q++) { short *curr = buckets[h]; h = (h + 1) & 0b111; a_ = curr[0]; while (a_ >= 1) { data[pc] = curr[a_]; pc++; a_--; } } } int main(int *argc, char **argv) { short data[LENGTH] = {}; srand(clock()); for (int i = 0; i < LENGTH; i++) { data[i] = rand() % 0xFFFF; } sort(data, LENGTH); printf("Num compares: %d\n", count); for (int i = 0; i < LENGTH; i++) { printf("%hd, ", data[i] & 0xFFFF); } printf("\n"); return 0; }