1 // See LICENSE for license details.
3 //**************************************************************************
5 //--------------------------------------------------------------------------
7 // This benchmark uses quicksort to sort an array of integers. The
8 // implementation is largely adapted from Numerical Recipes for C. The
9 // input data (and reference data) should be generated using the
10 // qsort_gendata.pl perl script and dumped to a file named
11 // dataset1.h The smips-gcc toolchain does not support system calls
12 // so printf's can only be used on a host system, not on the smips
13 // processor simulator itself. You should not change anything except
14 // the HOST_DEBUG and PREALLOCATE macros for your timing run.
20 // The INSERTION_THRESHOLD is the size of the subarray when the
21 // algorithm switches to using an insertion sort instead of
24 #define INSERTION_THRESHOLD 10
26 // NSTACK is the required auxiliary storage.
27 // It must be at least 2*lg(DATA_SIZE)
31 //--------------------------------------------------------------------------
32 // Input/Reference Data
37 // Swap macro for swapping two values.
39 #define SWAP(a,b) do { typeof(a) temp=(a);(a)=(b);(b)=temp; } while (0)
40 #define SWAP_IF_GREATER(a, b) do { if ((a) > (b)) SWAP(a, b); } while (0)
42 //--------------------------------------------------------------------------
45 static void insertion_sort(size_t n
, type arr
[])
49 for (i
= arr
+1; i
< arr
+n
; i
++)
53 while (value
< *(j
-1))
63 static void selection_sort(size_t n
, type arr
[])
65 for (type
* i
= arr
; i
< arr
+n
-1; i
++)
66 for (type
* j
= i
+1; j
< arr
+n
; j
++)
67 SWAP_IF_GREATER(*i
, *j
);
70 void sort(size_t n
, type arr
[])
75 type
** stackp
= stack
;
80 printArray( "", n
, arr
);
83 // Insertion sort when subarray small enough.
84 if ( ir
-l
< INSERTION_THRESHOLD
)
86 insertion_sort(ir
- l
+ 1, l
- 1);
88 if ( stackp
== stack
) break;
90 // Pop stack and begin a new round of partitioning.
96 // Choose median of left, center, and right elements as
97 // partitioning element a. Also rearrange so that a[l-1] <= a[l] <= a[ir-].
98 SWAP(arr
[((l
-arr
) + (ir
-arr
))/2-1], l
[0]);
99 SWAP_IF_GREATER(l
[-1], ir
[-1]);
100 SWAP_IF_GREATER(l
[0], ir
[-1]);
101 SWAP_IF_GREATER(l
[-1], l
[0]);
103 // Initialize pointers for partitioning.
107 // Partitioning element.
110 for (;;) { // Beginning of innermost loop.
111 while (*i
++ < a
); // Scan up to find element > a.
112 while (*(j
-- - 2) > a
); // Scan down to find element < a.
113 if (j
< i
) break; // Pointers crossed. Partitioning complete.
114 SWAP(i
[-1], j
[-1]); // Exchange elements.
115 } // End of innermost loop.
117 // Insert partitioning element.
122 // Push pointers to larger subarray on stack,
123 // process smaller subarray immediately.
126 assert(stackp
< stack
+NSTACK
);
145 //--------------------------------------------------------------------------
148 int main( int argc
, char* argv
[] )
150 // Output the input array
151 printArray( "input", DATA_SIZE
, input_data
);
152 printArray( "verify", DATA_SIZE
, verify_data
);
155 // If needed we preallocate everything in the caches
156 sort(DATA_SIZE
, verify_data
);
157 if (verify(DATA_SIZE
, input_data
, input_data
))
163 sort( DATA_SIZE
, input_data
);
166 // Print out the results
167 printArray( "test", DATA_SIZE
, input_data
);
170 return verify( DATA_SIZE
, input_data
, verify_data
);