mirror of
https://github.com/kmc7468/cs420.git
synced 2025-12-15 23:18:48 +00:00
Add benchmarks from riscv-tests
This commit is contained in:
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);
|
||||
}
|
||||
Reference in New Issue
Block a user