mirror of
https://github.com/kmc7468/cs420.git
synced 2025-12-14 22:38:46 +00:00
Add benchmarks from riscv-tests
This commit is contained in:
34
bench/LICENSE
Normal file
34
bench/LICENSE
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
The following files are distributed under the following license with modifications.
|
||||||
|
|
||||||
|
* median.c
|
||||||
|
* multiply.c
|
||||||
|
* qsort.c
|
||||||
|
* rsort.c
|
||||||
|
* spmv.c
|
||||||
|
* towers.c
|
||||||
|
* vvadd.c
|
||||||
|
|
||||||
|
Copyright (c) 2012-2015, The Regents of the University of California (Regents).
|
||||||
|
All Rights Reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are met:
|
||||||
|
1. Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
3. Neither the name of the Regents nor the
|
||||||
|
names of its contributors may be used to endorse or promote products
|
||||||
|
derived from this software without specific prior written permission.
|
||||||
|
|
||||||
|
IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
|
||||||
|
SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING
|
||||||
|
OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF REGENTS HAS
|
||||||
|
BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED
|
||||||
|
HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO OBLIGATION TO PROVIDE
|
||||||
|
MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
|
||||||
@@ -12,6 +12,13 @@ namespace model {
|
|||||||
#include <two_dimension_array.c>
|
#include <two_dimension_array.c>
|
||||||
#include <matrix.c>
|
#include <matrix.c>
|
||||||
#include <graph.c>
|
#include <graph.c>
|
||||||
|
#include <median.c>
|
||||||
|
#include <multiply.c>
|
||||||
|
#include <qsort.c>
|
||||||
|
#include <rsort.c>
|
||||||
|
#include <spmv.c>
|
||||||
|
#include <towers.c>
|
||||||
|
#include <vvadd.c>
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@@ -28,6 +35,14 @@ extern "C" {
|
|||||||
int matrix_add(int, int);
|
int matrix_add(int, int);
|
||||||
int graph_dijkstra(int, int);
|
int graph_dijkstra(int, int);
|
||||||
int graph_floyd_warshall(int, int);
|
int graph_floyd_warshall(int, int);
|
||||||
|
// From riscv-tests
|
||||||
|
int run_median(int, int);
|
||||||
|
int run_multiply(int, int);
|
||||||
|
int run_qsort(int, int);
|
||||||
|
int run_rsort(int, int);
|
||||||
|
int run_spmv(int, int);
|
||||||
|
int run_towers(int, int);
|
||||||
|
int run_vvadd(int, int);
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
@@ -80,6 +95,13 @@ int main() {
|
|||||||
cycles.push_back(evaluate("matrix_add", 30, matrix_add, model::matrix_add));
|
cycles.push_back(evaluate("matrix_add", 30, matrix_add, model::matrix_add));
|
||||||
cycles.push_back(evaluate("graph_dijkstra", 1000, graph_dijkstra, model::graph_dijkstra));
|
cycles.push_back(evaluate("graph_dijkstra", 1000, graph_dijkstra, model::graph_dijkstra));
|
||||||
cycles.push_back(evaluate("graph_floyd_warshall", 200, graph_floyd_warshall, model::graph_floyd_warshall));
|
cycles.push_back(evaluate("graph_floyd_warshall", 200, graph_floyd_warshall, model::graph_floyd_warshall));
|
||||||
|
cycles.push_back(evaluate("median", -1, run_median, model::run_median));
|
||||||
|
cycles.push_back(evaluate("mutiply", -1, run_multiply, model::run_multiply));
|
||||||
|
cycles.push_back(evaluate("qsort", -1, run_qsort, model::run_qsort));
|
||||||
|
cycles.push_back(evaluate("rsort", -1, run_rsort, model::run_rsort));
|
||||||
|
cycles.push_back(evaluate("spmv", -1, run_spmv, model::run_spmv));
|
||||||
|
cycles.push_back(evaluate("towers", -1, run_towers, model::run_towers));
|
||||||
|
cycles.push_back(evaluate("vvadd", -1, run_vvadd, model::run_vvadd));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculates the geometric mean.
|
// Calculates the geometric mean.
|
||||||
|
|||||||
70
bench/median.c
Normal file
70
bench/median.c
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
//**************************************************************************
|
||||||
|
// Median filter bencmark
|
||||||
|
//--------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// This benchmark performs a 1D three element median filter.
|
||||||
|
|
||||||
|
int input_median[400];
|
||||||
|
int results_median[400];
|
||||||
|
|
||||||
|
void median_data_init(int nonce) {
|
||||||
|
int i;
|
||||||
|
int x = nonce;
|
||||||
|
|
||||||
|
for (i = 0; i < 400; i++) {
|
||||||
|
x = (x * 97 + 17) % 1000;
|
||||||
|
input_median[i] = x;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void median(int n, int input[400], int results[400]) {
|
||||||
|
int A, B, C, i;
|
||||||
|
|
||||||
|
// Zero the ends
|
||||||
|
results[0] = 0;
|
||||||
|
results[n - 1] = 0;
|
||||||
|
|
||||||
|
// Do the filter
|
||||||
|
for (i = 1; i < (n - 1); i++) {
|
||||||
|
A = input[i - 1];
|
||||||
|
B = input[i];
|
||||||
|
C = input[i + 1];
|
||||||
|
|
||||||
|
if (A < B) {
|
||||||
|
if (B < C)
|
||||||
|
results[i] = B;
|
||||||
|
else if (C < A)
|
||||||
|
results[i] = A;
|
||||||
|
else
|
||||||
|
results[i] = C;
|
||||||
|
}
|
||||||
|
|
||||||
|
else {
|
||||||
|
if (A < C)
|
||||||
|
results[i] = A;
|
||||||
|
else if (C < B)
|
||||||
|
results[i] = B;
|
||||||
|
else
|
||||||
|
results[i] = C;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int verify_median(int n, int* test) {
|
||||||
|
int i;
|
||||||
|
int result = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < n; i++) {
|
||||||
|
int v = test[i];
|
||||||
|
result += v;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
int run_median(int dummy_0, int nonce) {
|
||||||
|
median_data_init(nonce);
|
||||||
|
median(400, input_median, results_median);
|
||||||
|
|
||||||
|
return verify_median(400, results_median);
|
||||||
|
}
|
||||||
65
bench/multiply.c
Normal file
65
bench/multiply.c
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
// *************************************************************************
|
||||||
|
// multiply filter bencmark
|
||||||
|
// -------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// This benchmark tests the software multiply implemenation.
|
||||||
|
|
||||||
|
int input1_multiply[100];
|
||||||
|
int input2_multiply[100];
|
||||||
|
int results_multiply[100];
|
||||||
|
|
||||||
|
void multiply_data_init(int nonce) {
|
||||||
|
int i;
|
||||||
|
int x = nonce;
|
||||||
|
int y = nonce;
|
||||||
|
|
||||||
|
for (i = 0; i < 100; i++) {
|
||||||
|
x = (x * 97 + 17) % 10009;
|
||||||
|
y = (y * 17 + 23) % 10007;
|
||||||
|
input1_multiply[i] = x;
|
||||||
|
input2_multiply[i] = y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int multiply(int x, int y) {
|
||||||
|
int i;
|
||||||
|
int result = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < 32; i++) {
|
||||||
|
if ((x & 0x1) == 1)
|
||||||
|
result = result + y;
|
||||||
|
|
||||||
|
x = x >> 1;
|
||||||
|
y = y << 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
int verify_multiply(int n, int* test) {
|
||||||
|
int i;
|
||||||
|
int result = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < n; i++) {
|
||||||
|
int t0 = input1_multiply[i];
|
||||||
|
int t1 = input2_multiply[i];
|
||||||
|
int v = results_multiply[i];
|
||||||
|
if (t0 * t1 != v)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
result += v;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
int run_multiply(int dummy_0, int nonce) {
|
||||||
|
int i;
|
||||||
|
|
||||||
|
multiply_data_init(nonce);
|
||||||
|
for (i = 0; i < 100; i++) {
|
||||||
|
results_multiply[i] = multiply(input1_multiply[i], input2_multiply[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return verify_multiply(100, results_multiply);
|
||||||
|
}
|
||||||
129
bench/qsort.c
Normal file
129
bench/qsort.c
Normal file
@@ -0,0 +1,129 @@
|
|||||||
|
//**************************************************************************
|
||||||
|
// Quicksort benchmark
|
||||||
|
//--------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// This benchmark uses quicksort to sort an array of integers. The
|
||||||
|
// implementation is largely adapted from Numerical Recipes for C.
|
||||||
|
|
||||||
|
int input_qsort_data[16384];
|
||||||
|
|
||||||
|
void qsort_data_init(int nonce) {
|
||||||
|
int i;
|
||||||
|
int x = nonce;
|
||||||
|
|
||||||
|
for (i = 0; i < 16384; i++) {
|
||||||
|
x = (x * 97 + 17) % 100000009;
|
||||||
|
input_qsort_data[i] = x;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void swap(int* a, int* b) {
|
||||||
|
int temp = *a;
|
||||||
|
*a = *b;
|
||||||
|
*b = temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
void swap_if_greater(int* a, int* b) {
|
||||||
|
if (*a > *b)
|
||||||
|
swap(a, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
void insertion_sort(int n, int* arr) {
|
||||||
|
int i, j;
|
||||||
|
int value;
|
||||||
|
for (i = 1; i < n; i++) {
|
||||||
|
value = arr[i];
|
||||||
|
j = i;
|
||||||
|
while (value < arr[j - 1]) {
|
||||||
|
arr[j] = arr[j - 1];
|
||||||
|
if (--j == 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
arr[j] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void qsort(int n, int arr[16384]) {
|
||||||
|
int ir = n;
|
||||||
|
int l = 1;
|
||||||
|
int stack[50];
|
||||||
|
int stackp = 0;
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
// Insertion sort when subarray small enough.
|
||||||
|
if (ir - l < 10) {
|
||||||
|
insertion_sort(ir - l + 1, &arr[l - 1]);
|
||||||
|
|
||||||
|
if (stackp == 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Pop stack and begin a new round of partitioning.
|
||||||
|
ir = stack[stackp--];
|
||||||
|
l = stack[stackp--];
|
||||||
|
} else {
|
||||||
|
// Choose median of left, center, and right elements as
|
||||||
|
// partitioning element a. Also rearrange so that a[l-1] <= a[l] <= a[ir-].
|
||||||
|
swap(&arr[(l + ir) / 2 - 1], &arr[l]);
|
||||||
|
swap_if_greater(&arr[l - 1], &arr[ir - 1]);
|
||||||
|
swap_if_greater(&arr[l], &arr[ir - 1]);
|
||||||
|
swap_if_greater(&arr[l - 1], &arr[l]);
|
||||||
|
|
||||||
|
// Initialize pointers for partitioning.
|
||||||
|
int i = l + 1;
|
||||||
|
int j = ir;
|
||||||
|
|
||||||
|
// Partitioning element.
|
||||||
|
int a = arr[l];
|
||||||
|
|
||||||
|
for (;;) { // Beginning of innermost loop.
|
||||||
|
while (arr[i++] < a)
|
||||||
|
; // Scan up to find element > a.
|
||||||
|
while (arr[(j-- - 2)] > a)
|
||||||
|
; // Scan down to find element < a.
|
||||||
|
if (j < i)
|
||||||
|
break; // Pointers crossed. Partitioning complete.
|
||||||
|
swap(&arr[i - 1], &arr[j - 1]); // Exchange elements.
|
||||||
|
} // End of innermost loop.
|
||||||
|
|
||||||
|
// Insert partitioning element.
|
||||||
|
arr[l] = arr[j - 1];
|
||||||
|
arr[j - 1] = a;
|
||||||
|
stackp += 2;
|
||||||
|
|
||||||
|
// Push pointers to larger subarray on stack,
|
||||||
|
// process smaller subarray immediately.
|
||||||
|
|
||||||
|
if (ir - i + 1 >= j - l) {
|
||||||
|
stack[stackp] = ir;
|
||||||
|
stack[stackp - 1] = i;
|
||||||
|
ir = j - 1;
|
||||||
|
} else {
|
||||||
|
stack[stackp] = j - 1;
|
||||||
|
stack[stackp - 1] = l;
|
||||||
|
l = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int verify_qsort(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 run_qsort(int dummy_0, int nonce) {
|
||||||
|
qsort_data_init(nonce);
|
||||||
|
qsort(16384, input_qsort_data);
|
||||||
|
|
||||||
|
return verify_qsort(16384, input_qsort_data);
|
||||||
|
}
|
||||||
117
bench/rsort.c
Normal file
117
bench/rsort.c
Normal file
@@ -0,0 +1,117 @@
|
|||||||
|
//**************************************************************************
|
||||||
|
// 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);
|
||||||
|
}
|
||||||
90
bench/spmv.c
Normal file
90
bench/spmv.c
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
//**************************************************************************
|
||||||
|
// Double-precision sparse matrix-vector multiplication benchmark
|
||||||
|
//--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
double val[2399];
|
||||||
|
int idx[2399];
|
||||||
|
|
||||||
|
double x[500];
|
||||||
|
int ptr[501] = {
|
||||||
|
0, 4, 8, 10, 15, 22, 29, 33, 34, 36, 39, 44, 44, 47, 55, 61, 66, 68, 75, 82, 86, 91, 98, 104, 109, 113, 126, 131, 134,
|
||||||
|
136, 143, 153, 159, 168, 170, 174, 176, 180, 187, 192, 198, 200, 204, 211, 213, 222, 225, 228, 233, 241, 247, 253, 256,
|
||||||
|
262, 264, 270, 274, 277, 283, 288, 294, 301, 307, 312, 315, 319, 325, 329, 332, 338, 340, 342, 348, 353, 359, 362, 366,
|
||||||
|
368, 374, 387, 393, 400, 403, 406, 412, 420, 425, 428, 433, 441, 442, 448, 456, 462, 468, 469, 477, 479, 485, 490, 495,
|
||||||
|
501, 508, 513, 518, 524, 532, 535, 538, 542, 546, 552, 561, 563, 567, 571, 574, 576, 581, 584, 588, 592, 593, 597, 599,
|
||||||
|
607, 612, 615, 619, 626, 633, 640, 646, 650, 653, 659, 665, 670, 673, 678, 685, 691, 697, 703, 708, 712, 717, 719, 722,
|
||||||
|
725, 732, 736, 738, 742, 747, 753, 757, 763, 767, 769, 769, 777, 780, 784, 790, 797, 807, 810, 813, 815, 817, 822, 829,
|
||||||
|
830, 835, 844, 848, 851, 854, 862, 864, 873, 876, 881, 884, 888, 895, 899, 901, 904, 908, 912, 919, 927, 931, 937, 941,
|
||||||
|
944, 948, 950, 955, 960, 963, 970, 975, 979, 983, 985, 992, 993, 998, 1001, 1008, 1012, 1014, 1018, 1023, 1030, 1036,
|
||||||
|
1040, 1045, 1052, 1058, 1061, 1066, 1069, 1071, 1077, 1080, 1084, 1087, 1090, 1092, 1095, 1100, 1102, 1110, 1117, 1122,
|
||||||
|
1130, 1133, 1138, 1142, 1144, 1146, 1153, 1158, 1160, 1167, 1172, 1176, 1179, 1183, 1188, 1191, 1193, 1196, 1204, 1210,
|
||||||
|
1216, 1219, 1221, 1225, 1229, 1234, 1236, 1239, 1244, 1248, 1253, 1256, 1264, 1268, 1271, 1272, 1275, 1278, 1284, 1287,
|
||||||
|
1291, 1296, 1300, 1304, 1306, 1313, 1317, 1322, 1326, 1332, 1336, 1344, 1349, 1356, 1363, 1368, 1369, 1378, 1381, 1385,
|
||||||
|
1388, 1395, 1399, 1407, 1414, 1422, 1425, 1433, 1435, 1438, 1439, 1445, 1448, 1450, 1453, 1456, 1470, 1472, 1475, 1481,
|
||||||
|
1487, 1491, 1494, 1497, 1498, 1503, 1507, 1513, 1517, 1524, 1529, 1534, 1542, 1547, 1550, 1550, 1552, 1553, 1556, 1559,
|
||||||
|
1563, 1571, 1577, 1580, 1585, 1590, 1594, 1598, 1600, 1602, 1610, 1615, 1620, 1628, 1634, 1637, 1649, 1652, 1656, 1662,
|
||||||
|
1664, 1670, 1674, 1678, 1687, 1697, 1704, 1709, 1715, 1720, 1725, 1728, 1736, 1740, 1747, 1750, 1754, 1760, 1763, 1765,
|
||||||
|
1773, 1781, 1783, 1788, 1795, 1802, 1810, 1815, 1820, 1824, 1829, 1836, 1839, 1843, 1847, 1849, 1854, 1859, 1863, 1873,
|
||||||
|
1880, 1882, 1891, 1895, 1899, 1904, 1909, 1914, 1919, 1923, 1927, 1932, 1938, 1943, 1949, 1954, 1960, 1965, 1968, 1974,
|
||||||
|
1980, 1983, 1990, 1992, 1995, 2002, 2011, 2017, 2024, 2028, 2035, 2037, 2048, 2055, 2063, 2067, 2069, 2078, 2081, 2085,
|
||||||
|
2086, 2090, 2097, 2101, 2107, 2110, 2112, 2116, 2119, 2122, 2129, 2136, 2143, 2146, 2156, 2162, 2171, 2175, 2179, 2186,
|
||||||
|
2189, 2194, 2198, 2206, 2211, 2215, 2222, 2228, 2237, 2241, 2245, 2256, 2259, 2269, 2272, 2275, 2278, 2279, 2281, 2287,
|
||||||
|
2292, 2297, 2304, 2311, 2316, 2319, 2322, 2327, 2333, 2340, 2343, 2345, 2350, 2358, 2365, 2365, 2368, 2373, 2379, 2388,
|
||||||
|
2394, 2399};
|
||||||
|
|
||||||
|
void spmv_init(int nonce) {
|
||||||
|
int i;
|
||||||
|
int t1 = nonce;
|
||||||
|
int t2 = nonce;
|
||||||
|
|
||||||
|
for (i = 0; i < 2399; i++) {
|
||||||
|
t1 = (t1 * 97 + 17) % 1000;
|
||||||
|
t2 = (t2 * 17 + 23) % 500;
|
||||||
|
val[i] = (double) t1;
|
||||||
|
idx[i] = t2;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < 500; i++) {
|
||||||
|
t1 = (t1 * 17 + 23) % 1000;
|
||||||
|
x[i] = (double) t1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void spmv(int r, double* val, int* idx, double* x, int* ptr, double* y) {
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < r; i++) {
|
||||||
|
int k;
|
||||||
|
double yi0 = 0, yi1 = 0, yi2 = 0, yi3 = 0;
|
||||||
|
for (k = ptr[i]; k < ptr[i + 1] - 3; k += 4) {
|
||||||
|
yi0 += val[k + 0] * x[idx[k + 0]];
|
||||||
|
yi1 += val[k + 1] * x[idx[k + 1]];
|
||||||
|
yi2 += val[k + 2] * x[idx[k + 2]];
|
||||||
|
yi3 += val[k + 3] * x[idx[k + 3]];
|
||||||
|
}
|
||||||
|
for (; k < ptr[i + 1]; k++) {
|
||||||
|
yi0 += val[k] * x[idx[k]];
|
||||||
|
}
|
||||||
|
y[i] = (yi0 + yi1) + (yi2 + yi3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int verifyDouble(int n, double* test) {
|
||||||
|
int i;
|
||||||
|
int result = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < n; i++) {
|
||||||
|
result += (int) (test[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
double y[500];
|
||||||
|
|
||||||
|
int run_spmv(int dummy_0, int nonce) {
|
||||||
|
spmv_init(nonce);
|
||||||
|
spmv(500, val, idx, x, ptr, y);
|
||||||
|
|
||||||
|
return verifyDouble(500, y);
|
||||||
|
}
|
||||||
193
bench/towers.c
Normal file
193
bench/towers.c
Normal file
@@ -0,0 +1,193 @@
|
|||||||
|
//**************************************************************************
|
||||||
|
// Towers of Hanoi benchmark
|
||||||
|
//--------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Towers of Hanoi is a classic puzzle problem. The game consists of
|
||||||
|
// three pegs and a set of discs. Each disc is a different size, and
|
||||||
|
// initially all of the discs are on the left most peg with the smallest
|
||||||
|
// disc on top and the largest disc on the bottom. The goal is to move all
|
||||||
|
// of the discs onto the right most peg. The catch is that you are only
|
||||||
|
// allowed to move one disc at a time and you can never place a larger
|
||||||
|
// disc on top of a smaller disc.
|
||||||
|
//
|
||||||
|
// This implementation starts with NUM_DISC discs and uses a recursive
|
||||||
|
// algorithm to solve the puzzle.
|
||||||
|
|
||||||
|
struct Node {
|
||||||
|
int val;
|
||||||
|
struct Node* next;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct List {
|
||||||
|
int size;
|
||||||
|
struct Node* head;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct List g_nodeFreeList;
|
||||||
|
struct Node g_nodePool[7];
|
||||||
|
|
||||||
|
int list_getSize(struct List* list) {
|
||||||
|
return list->size;
|
||||||
|
}
|
||||||
|
|
||||||
|
void list_init(struct List* list) {
|
||||||
|
list->size = 0;
|
||||||
|
list->head = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void list_push(struct List* list, int val) {
|
||||||
|
struct Node* newNode;
|
||||||
|
|
||||||
|
// Pop the next free node off the free list
|
||||||
|
newNode = g_nodeFreeList.head;
|
||||||
|
g_nodeFreeList.head = g_nodeFreeList.head->next;
|
||||||
|
|
||||||
|
// Push the new node onto the given list
|
||||||
|
newNode->next = list->head;
|
||||||
|
list->head = newNode;
|
||||||
|
|
||||||
|
// Assign the value
|
||||||
|
list->head->val = val;
|
||||||
|
|
||||||
|
// Increment size
|
||||||
|
list->size++;
|
||||||
|
}
|
||||||
|
|
||||||
|
int list_pop(struct List* list) {
|
||||||
|
struct Node* freedNode;
|
||||||
|
int val;
|
||||||
|
|
||||||
|
// Get the value from the->head of given list
|
||||||
|
val = list->head->val;
|
||||||
|
|
||||||
|
// Pop the head node off the given list
|
||||||
|
freedNode = list->head;
|
||||||
|
list->head = list->head->next;
|
||||||
|
|
||||||
|
// Push the freed node onto the free list
|
||||||
|
freedNode->next = g_nodeFreeList.head;
|
||||||
|
g_nodeFreeList.head = freedNode;
|
||||||
|
|
||||||
|
// Decrement size
|
||||||
|
list->size--;
|
||||||
|
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
void list_clear(struct List* list) {
|
||||||
|
while (list_getSize(list) > 0)
|
||||||
|
list_pop(list);
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------
|
||||||
|
// Tower data structure and functions
|
||||||
|
|
||||||
|
struct Towers {
|
||||||
|
int numDiscs;
|
||||||
|
int numMoves;
|
||||||
|
struct List pegA;
|
||||||
|
struct List pegB;
|
||||||
|
struct List pegC;
|
||||||
|
};
|
||||||
|
|
||||||
|
void towers_init(struct Towers* towers, int n, int nonce) {
|
||||||
|
int i;
|
||||||
|
|
||||||
|
towers->numDiscs = n;
|
||||||
|
towers->numMoves = 0;
|
||||||
|
|
||||||
|
list_init(&(towers->pegA));
|
||||||
|
list_init(&(towers->pegB));
|
||||||
|
list_init(&(towers->pegC));
|
||||||
|
|
||||||
|
for (i = 0; i < n; i++)
|
||||||
|
list_push(&(towers->pegA), nonce * (n - i));
|
||||||
|
}
|
||||||
|
|
||||||
|
void towers_clear(struct Towers* towers, int nonce) {
|
||||||
|
list_clear(&(towers->pegA));
|
||||||
|
list_clear(&(towers->pegB));
|
||||||
|
list_clear(&(towers->pegC));
|
||||||
|
|
||||||
|
towers_init(towers, towers->numDiscs, nonce);
|
||||||
|
}
|
||||||
|
|
||||||
|
void towers_solve_h(struct Towers* towers, int n, struct List* startPeg, struct List* tempPeg, struct List* destPeg) {
|
||||||
|
int val;
|
||||||
|
|
||||||
|
if (n == 1) {
|
||||||
|
val = list_pop(startPeg);
|
||||||
|
list_push(destPeg, val);
|
||||||
|
towers->numMoves++;
|
||||||
|
} else {
|
||||||
|
towers_solve_h(towers, n - 1, startPeg, destPeg, tempPeg);
|
||||||
|
towers_solve_h(towers, 1, startPeg, tempPeg, destPeg);
|
||||||
|
towers_solve_h(towers, n - 1, tempPeg, startPeg, destPeg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void towers_solve(struct Towers* towers) {
|
||||||
|
towers_solve_h(towers, towers->numDiscs, &(towers->pegA), &(towers->pegB), &(towers->pegC));
|
||||||
|
}
|
||||||
|
|
||||||
|
int towers_verify(struct Towers* towers, int nonce) {
|
||||||
|
struct Node* ptr;
|
||||||
|
int numDiscs = 0;
|
||||||
|
int result = 0;
|
||||||
|
|
||||||
|
if (list_getSize(&towers->pegA) != 0) {
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (list_getSize(&towers->pegB) != 0) {
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (list_getSize(&towers->pegC) != towers->numDiscs) {
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (ptr = towers->pegC.head; ptr != 0; ptr = ptr->next) {
|
||||||
|
numDiscs++;
|
||||||
|
if (ptr->val != nonce * numDiscs) {
|
||||||
|
return 5;
|
||||||
|
}
|
||||||
|
result += ptr->val;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (towers->numMoves != ((1 << towers->numDiscs) - 1)) {
|
||||||
|
return 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------
|
||||||
|
// Main
|
||||||
|
|
||||||
|
int run_towers(int dummy_0, int nonce) {
|
||||||
|
struct Towers towers;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
// Initialize free list
|
||||||
|
|
||||||
|
list_init(&g_nodeFreeList);
|
||||||
|
g_nodeFreeList.head = &(g_nodePool[0]);
|
||||||
|
g_nodeFreeList.size = 7;
|
||||||
|
g_nodePool[7 - 1].next = 0;
|
||||||
|
g_nodePool[7 - 1].val = 99;
|
||||||
|
for (i = 0; i < (7 - 1); i++) {
|
||||||
|
g_nodePool[i].next = &(g_nodePool[i + 1]);
|
||||||
|
g_nodePool[i].val = nonce * i;
|
||||||
|
}
|
||||||
|
|
||||||
|
towers_init(&towers, 7, nonce);
|
||||||
|
|
||||||
|
// Solve it
|
||||||
|
|
||||||
|
towers_clear(&towers, nonce);
|
||||||
|
towers_solve(&towers);
|
||||||
|
|
||||||
|
// Check the results
|
||||||
|
return towers_verify(&towers, nonce);
|
||||||
|
}
|
||||||
48
bench/vvadd.c
Normal file
48
bench/vvadd.c
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
//**************************************************************************
|
||||||
|
// Vector-vector add benchmark
|
||||||
|
//--------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// This benchmark uses adds to vectors and writes the results to a
|
||||||
|
// third vector.
|
||||||
|
|
||||||
|
int input1_vvadd[1000];
|
||||||
|
int input2_vvadd[1000];
|
||||||
|
int results_vvadd[1000];
|
||||||
|
|
||||||
|
void vvadd_init(int nonce) {
|
||||||
|
int i;
|
||||||
|
int x = nonce;
|
||||||
|
int y = nonce;
|
||||||
|
|
||||||
|
for (i = 0; i < 1000; i++) {
|
||||||
|
x = (x * 97 + 17) % 1009;
|
||||||
|
y = (x * 17 + 23) % 1007;
|
||||||
|
input1_vvadd[i] = x;
|
||||||
|
input2_vvadd[i] = y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void vvadd(int n, int a[1000], int b[1000], int c[1000]) {
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < n; i++)
|
||||||
|
c[i] = a[i] + b[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
int verify_vvadd(int n, int* test) {
|
||||||
|
int i;
|
||||||
|
int result = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < n; i++) {
|
||||||
|
int v = test[i];
|
||||||
|
result += v;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
int run_vvadd(int dummy_0, int nonce) {
|
||||||
|
vvadd_init(nonce);
|
||||||
|
vvadd(1000, input1_vvadd, input2_vvadd, results_vvadd);
|
||||||
|
return verify_vvadd(1000, results_vvadd);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user