mirror of
https://github.com/kmc7468/cs420.git
synced 2025-12-14 22:38:46 +00:00
118 lines
3.1 KiB
C
118 lines
3.1 KiB
C
//**************************************************************************
|
|
// Radix Sort benchmark
|
|
//--------------------------------------------------------------------------
|
|
//
|
|
// This benchmark uses radix sort to sort an array of integers. The
|
|
// implementation is largely adapted from Numerical Recipes for C.
|
|
|
|
int input_rsort_data[2048];
|
|
|
|
void rsort_data_init(int nonce) {
|
|
int i;
|
|
int x = nonce;
|
|
|
|
for (i = 0; i < 2048; i++) {
|
|
x = (x * 97 + 17) % 100007;
|
|
input_rsort_data[i] = x;
|
|
}
|
|
}
|
|
|
|
int fetch_add(int* ptr, int inc) {
|
|
return (*ptr += inc) - inc;
|
|
}
|
|
|
|
void memcpy_int(int* dest, int* src, int size) {
|
|
int i;
|
|
|
|
for (i = 0; i < size; i++) {
|
|
dest[i] = src[i];
|
|
}
|
|
}
|
|
|
|
int bucket[256];
|
|
|
|
void rsort(int n, int* arrIn, int* scratchIn) {
|
|
int log_exp = 0;
|
|
int *arr = arrIn, *scratch = scratchIn;
|
|
int p;
|
|
int b;
|
|
|
|
while (log_exp < 8 * sizeof(int)) {
|
|
for (b = 0; b < (1 << 8); b++)
|
|
bucket[b] = 0;
|
|
|
|
for (p = 0; p < n - 3; p += 4) {
|
|
int a0 = arr[p + 0];
|
|
int a1 = arr[p + 1];
|
|
int a2 = arr[p + 2];
|
|
int a3 = arr[p + 3];
|
|
fetch_add(&bucket[(a0 >> log_exp) % (1 << 8)], 1);
|
|
fetch_add(&bucket[(a1 >> log_exp) % (1 << 8)], 1);
|
|
fetch_add(&bucket[(a2 >> log_exp) % (1 << 8)], 1);
|
|
fetch_add(&bucket[(a3 >> log_exp) % (1 << 8)], 1);
|
|
}
|
|
for (; p < n; p++)
|
|
bucket[(arr[p] >> log_exp) % (1 << 8)]++;
|
|
|
|
int prev = bucket[0];
|
|
prev += fetch_add(&bucket[1], prev);
|
|
for (b = 2; b < (1 << 8); b += 2) {
|
|
prev += fetch_add(&bucket[b + 0], prev);
|
|
prev += fetch_add(&bucket[b + 1], prev);
|
|
}
|
|
|
|
for (p = n - 1; p >= 3; p -= 4) {
|
|
int a0 = arr[p - 0];
|
|
int a1 = arr[p - 1];
|
|
int a2 = arr[p - 2];
|
|
int a3 = arr[p - 3];
|
|
int* pb0 = &bucket[(a0 >> log_exp) % (1 << 8)];
|
|
int* pb1 = &bucket[(a1 >> log_exp) % (1 << 8)];
|
|
int* pb2 = &bucket[(a2 >> log_exp) % (1 << 8)];
|
|
int* pb3 = &bucket[(a3 >> log_exp) % (1 << 8)];
|
|
int s0 = fetch_add(pb0, -1);
|
|
int s1 = fetch_add(pb1, -1);
|
|
int s2 = fetch_add(pb2, -1);
|
|
int s3 = fetch_add(pb3, -1);
|
|
scratch[s0 - 1] = a0;
|
|
scratch[s1 - 1] = a1;
|
|
scratch[s2 - 1] = a2;
|
|
scratch[s3 - 1] = a3;
|
|
}
|
|
for (; p >= 0; p--)
|
|
scratch[--bucket[(arr[p] >> log_exp) % (1 << 8)]] = arr[p];
|
|
|
|
int* tmp = arr;
|
|
arr = scratch;
|
|
scratch = tmp;
|
|
|
|
log_exp += 8;
|
|
}
|
|
if (arr != arrIn)
|
|
memcpy_int(arr, scratch, n);
|
|
}
|
|
|
|
int verify_rsort(int n, int* test) {
|
|
int i;
|
|
int result = 0;
|
|
|
|
for (i = 0; i < n - 1; i++) {
|
|
int t0 = test[i], t1 = test[i + 1];
|
|
if (t0 > t1)
|
|
return 1;
|
|
|
|
result ^= t0;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
int scratch[2048];
|
|
|
|
int run_rsort(int dummy_0, int nonce) {
|
|
rsort_data_init(nonce);
|
|
rsort(2048, input_rsort_data, scratch);
|
|
|
|
return verify_rsort(2048, input_rsort_data);
|
|
}
|