added tools to test branch perdiction performance

This commit is contained in:
Nils K
2020-04-19 19:07:46 +02:00
parent e214510956
commit 7ae8d72435
5 changed files with 237 additions and 0 deletions

1
branch_predict_test/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
*.txt

View File

@@ -0,0 +1,2 @@
build: branch_predict.c
gcc branch_predict.c -O2 -o branch_predict.exe

Binary file not shown.

View File

@@ -0,0 +1,227 @@
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<time.h>
/*
* range of the chars in the randomly generated string
*
* 33 = '!'
* 127 = '~'
*
*/
#define CHAR_START 33
#define CHAR_END 127
/*
* returns dynamically allocated random string
* with a strlen between minLen and maxLen
* the memory size is strlen + 1
*
*/
char* rand_word(unsigned minLen, unsigned maxLen);
/*
* uses rand returned value >= min and value <= max
*/
unsigned rand_between(unsigned min, unsigned max);
/*
* returns an array of dynamically allocated strings
* length of array is n + 1, the last value is NULL
*/
char** random_strings(size_t n, unsigned minLen, unsigned maxLen);
/*
* returns strlen without newline
* removes terminates string at newline position
*/
size_t remove_newline(char* str);
/*max line size with newline and terminating 0*/
#define MAX_LINE_SIZE 1024
/*
* nRead, out: allowed to be NULL
* nRead represents actually read strings, without trailing NULL
* e.g. if 0 strings are read, nRead will be 0, and the returned array will be {NULL}
* returns string array, null terminated
*
*/
char** read_strings(const char* fileName, size_t* nRead);
/*
* count set bits in string s
*/
int string_bit_count(char* s);
/*
* returns malloced memory of size memSize
* if it fails, it exits with 7 the programm
*
*/
void* non_null_malloc(size_t memSize);
int string_sort_func(const void* a, const void* b);
void usage_and_exit();
void usage_and_exit() {
printf("usage\n");
printf("<prog> measure <filename>\n");
printf("<prog> sort <filename>\n");
printf("<prog> generate <n> <min> <max>\n");
exit(1);
}
int main(int argc, char* argv[])
{
_Bool generate = 0;
_Bool measure = 0;
_Bool sort = 0;
if(argc < 2 ) {
usage_and_exit();
}
measure = strcmp(argv[1], "measure") == 0;
generate = strcmp(argv[1], "generate") == 0;
sort = strcmp(argv[1], "sort") == 0;
if((!generate) && (!measure) && (!sort)) {
usage_and_exit();
}
if(measure) {
if(argc != 3 ) {
usage_and_exit();
}
char** array = read_strings(argv[2], NULL);
char** p = array;
unsigned long long counter = 0;
clock_t t1, t0 = clock();
for(; *p; ++p) {
counter += string_bit_count(*p);
}
t1 = clock();
printf("measure file: <%s>\n", argv[2]);
printf("counter = %llu\n", counter);
printf("time = %lf ms\n", (t1 - t0) / (double) CLOCKS_PER_SEC * 1000.0);
} else if(generate) {
if(argc != 5 ) {
usage_and_exit();
}
unsigned n, minLen, maxLen;
sscanf(argv[2], "%u", &n);
sscanf(argv[3], "%u", &minLen);
sscanf(argv[4], "%u", &maxLen);
char** words = random_strings(n, minLen, maxLen);
for(int i=0; i<n; ++i) {
printf("%s\n", words[i]);
}
} else if(sort) {
if(argc != 3 ) {
usage_and_exit();
}
size_t nRead = 0;
char** array = read_strings(argv[2], &nRead);
qsort(array, nRead, sizeof(char*), string_sort_func);
for(size_t i=0; i < nRead; ++i) {
printf("%s\n", array[i]);
}
}
}
size_t remove_newline(char* str) {
size_t pos = 0;
while(str[pos] && str[pos] != '\n') ++pos;
str[pos] = '\0';
return pos;
}
char** random_strings(size_t n, unsigned minLen, unsigned maxLen) {
char** array = (char**) non_null_malloc(sizeof(char*) * (n+1));
for(size_t i=0; i<n; ++i) {
array[i] = rand_word(minLen, maxLen);
}
array[n] = NULL;
return array;
}
void* non_null_malloc(size_t memSize) {
char* m = malloc(memSize);
if(!m) {
perror("non_malloc_failed");
exit(7);
}
return m;
}
unsigned rand_between(unsigned min, unsigned max) {
int rv = rand();
unsigned urv = rv < 0? -1*rv : rv;
unsigned v = (rv % ((max+1) - min)) + min;
return v;
}
char* rand_word(unsigned minLen, unsigned maxLen) {
unsigned len = rand_between(minLen, maxLen);
char* s = non_null_malloc(len+1);
for(size_t i=0; i<len; ++i) {
s[i] = rand_between(CHAR_START, CHAR_END);
}
s[len] = '\0';
return s;
}
int string_bit_count(char* s) {
//printf("<%s>\n", s);
int count = 0;
int len = strlen(s);
for(int i=0; i<len; ++i) {
for(int k=0; k<8; ++k) {
if(s[i] & (1 << k)) {
++count;
}
}
}
//printf("count = %d\n", count);
return count;
}
int string_sort_func(const void* a, const void* b) {
char* sa = *((char**) a);
char* sb = *((char**) b);
return strcmp(sa, sb);
}
char** read_strings(const char* fileName, size_t* nRead) {
size_t len;
char* sp;
FILE* f = fopen(fileName, "r");
if(!f) { perror("unable to open file"); exit(1); }
char* buff = non_null_malloc(MAX_LINE_SIZE);
size_t out_array_len = 16 * sizeof(char*);
size_t out_array_pos = 0;
char** out_array = non_null_malloc(out_array_len);
out_array[0] = NULL;
while(! feof(f)) {
buff[0] = '\0';
if(! fgets(buff, MAX_LINE_SIZE, f)) {
break;
}
len = remove_newline(buff);
if(len > 0) {
sp = non_null_malloc(len+1);
memcpy(sp, buff, len+1);
if(out_array_pos + 1 > out_array_len / sizeof(char*)) {
out_array_len = out_array_len * 2;
out_array = realloc(out_array, out_array_len);
if(! out_array) { perror("allocation failed"); exit(1); }
}
out_array[out_array_pos++] = sp;
out_array[out_array_pos] = NULL;
}
}
fclose(f);
if(nRead) *nRead = out_array_pos;
return out_array;
}

View File

@@ -0,0 +1,7 @@
./branch_predict generate 5000000 10 10 > unsorted_sample01.txt
./branch_predict sort unsorted_sample01.txt > issorted_sample01.txt
echo "head of unsorted_sample01.txt" >> output.txt
head unsorted_sample01.txt >> output.txt
echo "\n" >> output.txt
./branch_predict measure unsorted_sample01.txt >> output.txt
./branch_predict measure issorted_sample01.txt >> output.txt