Files
cs420/bench/rsort.c
2025-04-25 13:00:42 +09:00

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) % 10000007;
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);
}