Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor benchmark tests #200

Merged
merged 1 commit into from
Nov 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
143 changes: 35 additions & 108 deletions test/wasmBenchmarker/ctests/heapsort.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,109 +15,22 @@
*/

#include <stdio.h>
#include <stdint.h>

#define ARRAY_LENGTH 32000
#define ITERATIONS 16
#include "include/random.h"

// constants for the random numbers
#define m UINT16_MAX
#define a 33278
#define c 1256
#define seed 55682
#define ARRAY_LENGTH 15000
#define ITERATIONS 64

#define NO_CHILD 0
#define NO_PARENT UINT16_MAX
#define NO_PARENT 65535

/**
* Generate random number according to
* the linear congruential generator (LCG).
*
* Xˇ(n+1) = (a * Xˇ(n) + c) mod m
*
* where:
* - 0 < m
* - 0 < a < m
* - 0 <= c < m
* - 0 <= Xˇ(0) <= m
*/
uint16_t random();


/**
* Sort the given array according to
* the heapsort algorithm.
*/
void heapsort(uint16_t array[], uint16_t array_length);


/**
* Convert a heap to a max-heap
* (where parents have greater value than their children)
*/
void toMaxHeap(uint16_t array[], uint16_t array_length);


/**
* Set the children's index accordingly.
*
* If there's no child, it sets NO_CHILD.
*/
void getChildrenIndex(uint16_t array_length, uint16_t parentIndex, uint16_t *childIndex1, uint16_t *childIndex2);


/**
* Set the parent's index.
*
* If there is no parent, it returns NO_PARENT.
*/
uint16_t getParentIndex(uint16_t childIndex);


/**
* Correct the tree if needed from the given index
* to be correct to the max heap.
*/
void correct(uint16_t array[], uint16_t array_length, uint16_t elementInxex);


/**
* Swap the values of given elements
*/
void swap(uint16_t array[], uint16_t elementIndex1, uint16_t elementIndex2);


uint8_t runtime();


int main() {
printf("%u\n", (unsigned int) runtime());
return 0;
}


uint16_t random() {
static uint16_t previous = seed;
previous = (a * previous + c) % m;
return previous;
}

void heapsort(uint16_t array[], uint16_t array_length) {
toMaxHeap(array, array_length);
while (array_length > 1) {
swap(array, 0, array_length - 1);
array_length -= 1;
correct(array, array_length, 0);
}
}

void toMaxHeap(uint16_t array[], uint16_t array_length) {
for (int i = array_length - 1; i >= 1; i--) {
correct(array, array_length, getParentIndex(i));
}
void swap(unsigned int array[], unsigned int elementIndex1, unsigned int elementIndex2) {
unsigned int temp = array[elementIndex1];
array[elementIndex1] = array[elementIndex2];
array[elementIndex2] = temp;
}

void getChildrenIndex(uint16_t array_length, uint16_t parentIndex, uint16_t *childIndex1, uint16_t *childIndex2) {
void getChildrenIndex(unsigned int array_length, unsigned int parentIndex, unsigned int* childIndex1, unsigned int* childIndex2) {
if (array_length > (parentIndex * 2) + 1) {
*childIndex1 = (parentIndex * 2) + 1;
if (array_length > (parentIndex * 2) + 2) {
Expand All @@ -131,17 +44,17 @@ void getChildrenIndex(uint16_t array_length, uint16_t parentIndex, uint16_t *chi
}
}

uint16_t getParentIndex(uint16_t childIndex) {
unsigned int getParentIndex(unsigned int childIndex) {
if (childIndex == 0) {
return NO_PARENT;
} else {
return (childIndex - 1) / 2;
}
}

void correct(uint16_t array[], uint16_t array_length, uint16_t elementInxex) {
uint16_t childIndex1;
uint16_t childIndex2;
void correct(unsigned int array[], unsigned int array_length, unsigned int elementInxex) {
unsigned int childIndex1;
unsigned int childIndex2;
getChildrenIndex(array_length, elementInxex, &childIndex1, &childIndex2);
if (childIndex1 == NO_CHILD && childIndex2 == NO_CHILD) {
return;
Expand All @@ -168,26 +81,40 @@ void correct(uint16_t array[], uint16_t array_length, uint16_t elementInxex) {
}
}

void swap(uint16_t array[], uint16_t elementIndex1, uint16_t elementIndex2) {
uint16_t temp = array[elementIndex1];
array[elementIndex1] = array[elementIndex2];
array[elementIndex2] = temp;
void toMaxHeap(unsigned int array[], unsigned int array_length) {
for (unsigned int i = array_length - 1; i >= 1; i--) {
correct(array, array_length, getParentIndex(i));
}
}

uint8_t runtime() {
for (int i = 0; i < ITERATIONS; i++) {
uint16_t array[ARRAY_LENGTH];
void heapsort(unsigned int array[], unsigned int array_length) {
toMaxHeap(array, array_length);
while (array_length > 1) {
swap(array, 0, array_length - 1);
array_length--;
correct(array, array_length, 0);
}
}

int runtime() {
for (unsigned int i = 0; i < ITERATIONS; i++) {
unsigned int array[ARRAY_LENGTH];
for (int j = 0; j < ARRAY_LENGTH; j++) {
array[j] = random();
}

heapsort(array, ARRAY_LENGTH);

for (int j = 0; j < ARRAY_LENGTH - 1; j++) {
for (unsigned int j = 0; j < ARRAY_LENGTH - 1; j++) {
if (array[j] > array[j + 1]) {
return j;
}
}
}
return 0;
}

int main() {
printf("%d\n", runtime());
return 0;
}
106 changes: 106 additions & 0 deletions test/wasmBenchmarker/ctests/include/memory.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
#ifndef MEMORY_H
#define MEMORY_H

#define nullptr ((void*)0)

#ifndef MEMORY_SIZE
#define MEMORY_SIZE (15 * 1024) // in bytes
#endif

#ifndef RECORDS_SIZE
#define RECORDS_SIZE 1024 // in pieces
#endif

char memory[MEMORY_SIZE];

typedef struct {
void* address;
unsigned int size;
} record;

unsigned int recordsCurrentSize = 0;
record records[RECORDS_SIZE]; // Memory Allocation Table

/**
* @brief Allocate memory with uninitialised values.
* @param size the size of the memory to be allocated in bytes.
* @return the address of the memory, or nullptr if allocation fails.
*/
void* allocateMemory(unsigned int size) {
if (size > MEMORY_SIZE || size == 0 || recordsCurrentSize == RECORDS_SIZE) {
return nullptr;
}
for (unsigned int i = 0; i <= MEMORY_SIZE - size; i++) {
bool collision = false;
for (unsigned int j = 0; j < recordsCurrentSize; j++) {
if (
(((void*)memory + i) <= records[j].address && records[j].address <= ((void*)memory + i + size - 1)) ||
(((void*)memory + i) <= (records[j].address + records[j].size - 1) && (records[j].address + records[j].size - 1) <= ((void*)memory + i + size - 1)) ||
(records[j].address <= ((void*)memory + i) && ((void*)memory + i + size - 1) <= (records[j].address + records[j].size - 1))
) {
collision = true;
break;
}
}
if (collision == false) {
records[recordsCurrentSize].address = memory + i;
records[recordsCurrentSize].size = size;
recordsCurrentSize++;
return records[recordsCurrentSize - 1].address;
}
}
return nullptr;
}

/**
* @brief Free the memory at the given address.
* @param ptr address of the memory to be freed.
*/
void freeMemory(void* ptr) {
if (ptr == nullptr) return;
for (unsigned int i = 0; i < recordsCurrentSize; i++) {
if (records[i].address == ptr) {
for (unsigned int j = i; j < recordsCurrentSize - 1; j++) {
records[j].address = records[j + 1].address;
records[j].size = records[j + 1].size;
}
recordsCurrentSize--;
}
}
}

/**
* @brief Resize the given allocated memory.
* Its values will be identical to the values of the
* original memory up to the lesser size.
* @param ptr the pointer of the original memory.
* @param newSize the size of the new memory in bytes.
* @return the address of the new memory, or nullptr if reallocation fails.
*/
void* reallocateMemory(void* ptr, unsigned int newSize) {
if (newSize == 0) {
freeMemory(ptr);
return nullptr;
}
if (ptr == nullptr) {
return allocateMemory(newSize);
}
unsigned int index = 0;
while (ptr != records[index].address) {
index++;
}
if (newSize <= records[index].size) {
records[index].size = newSize;
return records[index].address;
}
void* newMem = allocateMemory(newSize);
if (newMem != nullptr) {
for (unsigned int i = 0; i < records[index].size; i++) {
((char*)newMem)[i] = ((char*)ptr)[i];
}
}
freeMemory(ptr);
return newMem;
}

#endif //MEMORY_H
44 changes: 44 additions & 0 deletions test/wasmBenchmarker/ctests/include/random.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* Copyright (c) 2023-present Samsung Electronics Co., Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#ifndef RANDOM_H
#define RANDOM_H

// constants for the random number generator
#define m 65535
#define a 33278
#define c 1256
#define seed 55682

/**
* Generate random number according to
* the linear congruential generator (LCG).
*
* Xˇ(n+1) = (a * Xˇ(n) + c) mod m
*
* where:
* - 0 < m
* - 0 < a < m
* - 0 <= c < m
* - 0 <= Xˇ(0) <= m
*/
unsigned int random() {
static unsigned int previous = seed;
previous = (a * previous + c) % m;
return previous;
}

#endif // RANDOM_H
Loading