1
0
Fork 0
mirror of https://github.com/hermitcore/libhermit.git synced 2025-03-09 00:00:03 +01:00
Stefan Lankes 2015-10-09 22:17:57 +02:00
parent 2946296f75
commit ac2c7ddf72
17 changed files with 1179 additions and 3 deletions

1
hermit/.gitignore vendored
View file

@ -20,5 +20,6 @@ usr/tests/hellof
usr/tests/jacobi
usr/tests/thr_hello
usr/benchmarks/stream
usr/benchmarks/hg
usr/x86/
usr/tmp/

View file

@ -43,7 +43,7 @@ endif
default: all
all: stream
all: stream hg
stream.o: stream.c
@echo [CC] $@
@ -56,13 +56,20 @@ stream: stream.o
$Q$(OBJCOPY_FOR_TARGET) $(STRIP_DEBUG) $@
$Qchmod a-x $@.sym
hg: hg.o hist.o rdtsc.o run.o init.o opt.o report.o setup.o
@echo [LD] $@
$Q$(CC_FOR_TARGET) $(LDFLAGS_FOR_TARGET) $(CFLAGS_FOR_TARGET) -o $@ $< hist.o rdtsc.o run.o init.o opt.o report.o setup.o
$Q$(OBJCOPY_FOR_TARGET) $(KEEP_DEBUG) $@ $@.sym
$Q$(OBJCOPY_FOR_TARGET) $(STRIP_DEBUG) $@
$Qchmod a-x $@.sym
clean:
@echo Cleaning benchmarks
$Q$(RM) stream *.sym *.o *~
$Q$(RM) stream hg *.sym *.o *~
veryclean:
@echo Propper cleaning benchmarks
$Q$(RM) stream *.sym *.o *~
$Q$(RM) stream hg *.sym *.o *~
depend:
$Q$(CC_FOR_TARGET) -MM $(CFLAGS_FOR_TARGET) *.c > Makefile.dep

View file

@ -0,0 +1,51 @@
/*
* =====================================================================================
*
* Filename: main.c
*
* Description:
*
* Version: 1.0
* Created: 25.07.2014 14:59:20
* Revision: none
* Compiler: gcc
*
* Author: Georg Wassen (gw) (),
* Company:
*
* =====================================================================================
*/
#include "opt.h"
#include "init.h"
#include "setup.h"
#include "run.h"
#include "report.h"
#include <stdio.h>
#include <stdlib.h>
struct opt opts = {0};
struct result results = {0};
int main(int argc, char *argv[])
{
printf("hourglass\n");
opt(argc, argv, &opts);
init(&opts);
report_params(&opts);
setup(&opts);
run(&opts, &results);
setdown(&opts);
report(&opts, &results);
run_free(&opts, &results);
deinit(&opts);
return EXIT_SUCCESS;
}

View file

@ -0,0 +1,78 @@
/*
* =====================================================================================
*
* Filename: hist.c
*
* Description:
*
* Version: 1.0
* Created: 26.07.2014 20:02:34
* Revision: none
* Compiler: gcc
*
* Author: Georg Wassen (gw) (),
* Company:
*
* =====================================================================================
*/
#include "hist.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
static const struct opt *opts;
static uint32_t *hists;
uint32_t *hist_alloc(const struct opt *opt)
{
opts = opt;
hists = calloc(opt->hist_cnt, sizeof(uint32_t));
hist_reset();
return hists;
}
int hist_reset(void)
{
unsigned i;
for (i=0; i<opts->hist_cnt; i++) {
hists[i] = 0;
}
return 0;
}
void hist_add(uint64_t t)
{
t /= opts->hist_width;
if (t > opts->hist_cnt-1) t = opts->hist_cnt-1;
hists[t]++;
}
int hist_print(void)
{
unsigned i;
unsigned max=0;
const size_t bar_width = 30;
char bar[bar_width+1];
for (i=0; i<opts->hist_cnt; i++) {
if (hists[i] > max) max = hists[i];
}
max = (unsigned)ceil(log10((double)max));
if (max == 0) max = 1;
memset(bar, '*', bar_width);
bar[bar_width] = 0;
printf("Histogram (%u bins with %u ticks each)\n", opts->hist_cnt, opts->hist_width);
for (i=0; i<opts->hist_cnt; i++) {
printf(" %5u : %5u..%5u : %-10u %s\n", i,
(unsigned)(i*opts->hist_width),
(unsigned)((i+1)*opts->hist_width-1),
(unsigned)(hists[i]),
(char*)bar+(unsigned)(bar_width-((log10(hists[i]+1.)*bar_width)/max)));
}
return 0;
}

View file

@ -0,0 +1,31 @@
/*
* =====================================================================================
*
* Filename: hist.h
*
* Description:
*
* Version: 1.0
* Created: 26.07.2014 20:02:48
* Revision: none
* Compiler: gcc
*
* Author: Georg Wassen (gw) (),
* Company:
*
* =====================================================================================
*/
#ifndef __HIST_H__
#define __HIST_H__
#include "opt.h"
#include <stdint.h>
uint32_t *hist_alloc(const struct opt *opt);
int hist_reset(void);
void hist_add(uint64_t t);
int hist_print(void);
#endif // __HIST_H__

View file

@ -0,0 +1,47 @@
/*
* =====================================================================================
*
* Filename: init.c
*
* Description:
*
* Version: 1.0
* Created: 25.07.2014 15:06:05
* Revision: none
* Compiler: gcc
*
* Author: Georg Wassen (gw) (),
* Company:
*
* =====================================================================================
*/
#include "init.h"
#include "rdtsc.h"
int init(struct opt *opt)
{
/*
* initialize (if required)
* e.g. read number of processors available or cache parameters
*/
opt->tps = rdtsc_ticks_per_sec(); // does not work reliably...
//opt->tps = 2530000000;
return 0;
}
int deinit(struct opt *opt)
{
/*
* de-initialize (if required)
* e.g. free allocated resources
*/
return 0;
}

View file

@ -0,0 +1,27 @@
/*
* =====================================================================================
*
* Filename: init.h
*
* Description:
*
* Version: 1.0
* Created: 25.07.2014 15:05:13
* Revision: none
* Compiler: gcc
*
* Author: Georg Wassen (gw) (),
* Company:
*
* =====================================================================================
*/
#ifndef __INIT_H__
#define __INIT_H__
#include "opt.h"
int init(struct opt *opt);
int deinit(struct opt *opt);
#endif // __INIT_H__

124
hermit/usr/benchmarks/opt.c Normal file
View file

@ -0,0 +1,124 @@
/*
* =====================================================================================
*
* Filename: opt.c
*
* Description:
*
* Version: 1.0
* Created: 25.07.2014 15:01:32
* Revision: none
* Compiler: gcc
*
* Author: Georg Wassen (gw) (),
* Company:
*
* =====================================================================================
*/
#define _GNU_SOURCE
#include "opt.h"
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <libgen.h>
#ifdef __hermit__
char *basename(char *path)
{
char *p;
if( path == NULL || *path == '\0' )
return ".";
p = path + strlen(path) - 1;
while( *p == '/' ) {
if( p == path )
return path;
*p-- = '\0';
}
while( p >= path && *p != '/' )
p--;
return p + 1;
}
#endif
int opt(int argc, char *argv[], struct opt *opt)
{
char c;
char *p;
opt->secs = 4;
opt->mode = stat;
opt->threshold = 0;
opt->hist_cnt = 100;
opt->hist_width = 50;
opt->list_cnt = 1000;
/*
* read command line arguments and store them in opt
*/
while ((c = getopt(argc, argv, "b:c:d:hr:t:")) != -1) {
switch (c) {
case 'h' :
printf("usage: %s <options>\n", basename(argv[0]));
printf(" -h help \n");
printf(" -d N duration (in sec or 1m, 1h) \n");
printf(" -r R report: hist, list\n");
printf(" -c N count (hist or list)\n");
printf(" -b N hist bin width (in ticks)\n");
printf(" -t N threshold (in ticks)\n");
exit(1);
break;
case 'd' :
opt->secs = (unsigned)strtoul(optarg, &p, 0);
if (p[0] == 'm' || p[0] == 'M') opt->secs *= 60u;
else if (p[0] == 'h' || p[0] == 'H') opt->secs *= (60u*60u);
else if (strlen(p) > 0) {
printf("ERROR: Parameter: unrecognized characters in time: '%s'\n", p);
return 2;
}
break;
case 'r' :
if (strncmp(optarg, "hist", 4) == 0) {
opt->mode = hist;
} else if (strncmp(optarg, "list", 4) == 0) {
opt->mode = list;
}
break;
case 'c' :
if (opt->mode == hist) {
opt->hist_cnt = (unsigned)strtoul(optarg, &p, 0);
} else if (opt->mode == list) {
opt->list_cnt = (unsigned)strtoul(optarg, &p, 0);
}
break;
case 'b' :
opt->hist_width = (unsigned)strtoul(optarg, &p, 0);
break;
case 't' :
opt->threshold = (unsigned)strtoul(optarg, &p, 0);
break;
}
}
if (opt->mode == hist) {
if (opt->hist_cnt == 0) {
opt->hist_cnt = 1;
}
if (opt->hist_width == 0) {
opt->hist_width = 1;
}
} else if (opt->mode == list) {
if (opt->list_cnt == 0) {
opt->list_cnt = 1;
}
}
return 0;
}

View file

@ -0,0 +1,38 @@
/*
* =====================================================================================
*
* Filename: opt.h
*
* Description:
*
* Version: 1.0
* Created: 25.07.2014 15:02:15
* Revision: none
* Compiler: gcc
*
* Author: Georg Wassen (gw) (),
* Company:
*
* =====================================================================================
*/
#ifndef __OPT_H__
#define __OPT_H__
#include <stdint.h>
struct opt {
unsigned secs;
enum {stat, hist, list} mode;
uint64_t tps;
uint64_t threshold;
unsigned hist_cnt;
unsigned hist_width;
unsigned list_cnt;
};
int opt(int argc, char *argv[], struct opt *opt);
#endif // __OPT_H__

View file

@ -0,0 +1,314 @@
/*
* =====================================================================================
*
* Filename: rdtsc.c
*
* Description:
*
* Version: 1.0
* Created: 31.01.2011 10:56:58
* Revision: none
* Compiler: gcc
*
* Author: Georg Wassen (gw) (),
* Company:
*
* =====================================================================================
*/
#define _SVID_SOURCE
#define _XOPEN_SOURCE 500
#include <sys/time.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <ctype.h>
#include "rdtsc.h"
static inline void cpuid(unsigned func, unsigned *eax, unsigned *ebx, unsigned *ecx, unsigned *edx) {
__asm__ volatile ("cpuid" : "=a"(*eax), "=b"(*ebx), "=c"(*ecx), "=d"(*edx) : "a"(func));
}
static inline uint32_t cpuid_edx(uint32_t code) {
uint32_t eax, ebx, ecx, edx;
cpuid(code, &eax, &ebx, &ecx, &edx);
return edx;
}
static uint64_t tps = 0;
#if 0
/*
* === FUNCTION ======================================================================
* Name: second()
* Description: returns a double representation of gettimeofday (seconds.microseconds)
* =====================================================================================
*/
static inline double second()
{
struct timeval tv;
gettimeofday(&tv, 0);
return tv.tv_sec + 1e-6*tv.tv_usec;
}
/*
* === FUNCTION ======================================================================
* Name: selectsleep(us)
* Description: calls select() to sleep (wait) the given microseconds
* =====================================================================================
*/
static inline void selectsleep(unsigned us)
{
struct timeval tv;
tv.tv_sec = 0;
tv.tv_usec = us;
select(0,0,0,0,&tv); // portable way to sleep with subsecond precision
}
/*
* === FUNCTION ======================================================================
* Name: rdtsc_ticks_per_sec()
* Description: uses least squares regressen to measure the frequency of the TSC
* =====================================================================================
*/
uint64_t rdtsc_ticks_per_sec(void)
{
double sumx = 0, sumy = 0;
double sumxx = 0, sumxy = 0;
double slope;
// least squared linear regression taken from mcert/misc/realfeed/realfeel.c
const unsigned n = 30;
unsigned i;
for (i=0; i<n; i++) {
double breal, real, ticks;
uint64_t bticks = 0, aticks = 0;
rdtsc(&bticks);
breal = second();
selectsleep((unsigned)(10000 + drand48() * 20000));
rdtsc(&aticks);
real = second() -breal;
ticks = (double)(aticks - bticks);
sumx += real;
sumxx += real * real;
sumxy += real * ticks;
sumy += ticks;
}
slope = ((sumxy - (sumx*sumy) / n) / (sumxx - (sumx*sumx) / n));
tps = (uint64_t)slope;
return tps;
}
#endif
uint64_t rdtsc_ticks_per_sec(void)
{
#ifdef __hermit__
uint64_t tps = (uint64_t) get_cpufreq() * 1000000ULL;
return tps;
#else
uint64_t t1, t2, t3, t4;
struct timeval tv1, tv2;
uint64_t diff_tsc, diff_usec;
rdtsc(&t1);
gettimeofday(&tv1, 0);
rdtsc(&t2);
usleep(500000); // 0.5 sec
rdtsc(&t3);
gettimeofday(&tv2, 0);
rdtsc(&t4);
//printf("t2-t1 : %llu\n", (unsigned long long)t2-t1);
//printf("t4-t3 : %llu\n", (unsigned long long)t4-t3);
t1 = (t1+t2)/2;
t2 = (t3+t4)/2;
diff_tsc = t2-t1;
//printf("diff tsc: %llu\n", (unsigned long long)diff_tsc);
diff_usec = (tv2.tv_sec - tv1.tv_sec) * 1000000;
if (tv2.tv_usec > tv1.tv_usec)
diff_usec += tv2.tv_usec - tv1.tv_usec;
else
diff_usec += tv1.tv_usec - tv2.tv_usec;
//printf("diff usec: %llu\n",
// (unsigned long long)diff_usec);
return (diff_tsc*1000000) / diff_usec;
#endif
}
/*
* === FUNCTION ======================================================================
* Name: rdtsc_max_freq(id)
* Description: reads the maximum frequency of given CPU-ID from /sys/.../cpuN/cpufreq
* Changes: WASSEN, 24.5.2011: taken from hourglass via irqlab
* =====================================================================================
*/
uint64_t rdtsc_max_freq(int id)
{
uint64_t mhz = -1;
char fname[BUFSIZ];
char processor[BUFSIZ];
char *buffer, *loc;
FILE *fp;
double tmhz;
int ret;
sprintf(fname, "/sys/devices/system/cpu/cpu%d/cpufreq/cpuinfo_max_freq", id);
if (NULL == (fp = fopen(fname, "r"))) {
fprintf(stderr, "Can't open <%s>.\n", fname);
fprintf(stderr, "Trying </proc/cpuinfo> (not as accurate)\n");
if(NULL == (fp = fopen("/proc/cpuinfo","r"))) {
fprintf(stderr, "Can't open </proc/cpuinfo>.\n");
return -1;
}
buffer = (void *) malloc(sizeof(char) * 1024 * 512);
ret = fread(buffer, sizeof(char), 1024 * 512, fp);
if (ret == 0) {
fprintf(stderr, "fread() returned 0: %s\n", strerror(errno));
return -1;
}
sprintf(processor, "processor\t: %d", id);
if(NULL == (loc = strstr(buffer, processor))) {
fprintf(stderr, "Unable to parse /proc/cpuinfo\n");
return -1;
}
if(NULL == (loc = strstr(loc, "cpu MHz"))) {
fprintf(stderr, "Unable to parse /proc/cpuinfo\n");
return -1;
}
loc += strlen("cpu MHz");
while(!isdigit(*loc))
loc++;
loc--;
sscanf(loc, "%lf", &tmhz);
mhz = (uint64_t)(tmhz);
mhz*=1000;
free(buffer);
} else {
ret = fscanf(fp, "%lld", (unsigned long long*)&mhz);
if (ret == 0) {
fprintf(stderr, "fscanf() returned 0: %s\n", strerror(errno));
return -1;
}
fclose(fp);
}
return mhz*1000;
}
/*
* === FUNCTION ======================================================================
* Name: rdtsc_loop(ticks)
* Description: waits actively for given TSC ticks
* =====================================================================================
*/
void rdtsc_loop(uint64_t ticks)
{
uint64_t t_now = 0, t_end;
rdtsc(&t_now);
t_end = t_now + ticks;
while (t_now < t_end) {
rdtsc(&t_now);
}
}
/*
* === FUNCTION ======================================================================
* Name: rdtsc_loop_sec(ticks)
* Description: waits actively for given seconds
* ATTN: needs rdtsc_ticks_per_sec() unless that function was previously
* called (this function MIGHT use syscalls!)
* =====================================================================================
*/
void rdtsc_loop_sec(unsigned seconds)
{
uint64_t t_now = 0, t_end;
rdtsc(&t_now);
if (tps == 0) rdtsc_ticks_per_sec();
t_end = t_now + (uint64_t)seconds * tps;
while (t_now < t_end) {
rdtsc(&t_now);
}
}
/*
* test if TSC is invariant (return value 1)
*/
int rdtsc_is_invariant(void) {
if (cpuid_edx(0x80000007) & (1 << 8)) { // TSC is invariant
return 1;
}
return 0;
}
/*
* measure overhead of *not* serialized rdtsc() (SHL, MOV, OR)
*/
uint64_t rdtsc_get_overhead(const uint64_t iterations) {
uint64_t c;
uint64_t tsc_overhead_notserial = 0;
uint64_t tsc_start;
uint64_t tsc_end;
if (iterations == 0) {
return 0;
}
for (c = 0; c < iterations; c++) {
#if ! __MIC__
__asm__ volatile("lfence");
#else
__asm__ volatile("lock; add $0, 0(%%rsp)" ::: "memory");
#endif
rdtsc(&tsc_start);
rdtsc(&tsc_end);
tsc_overhead_notserial += tsc_end - tsc_start;
}
return tsc_overhead_notserial / iterations;
}
/*
* measure overhead of serialized rdtsc_serialized() (LFENCE, SHL, MOV, OR, LFENCE)
*/
uint64_t rdtsc_get_overhead_serialized(const uint64_t iterations) {
uint64_t c;
uint64_t tsc_overhead_serial = 0;
uint64_t tsc_start;
uint64_t tsc_end;
if (iterations == 0) {
return 0;
}
for (c = 0; c < iterations; c++) {
rdtsc_serialized(&tsc_start);
rdtsc_serialized(&tsc_end);
tsc_overhead_serial += tsc_end - tsc_start;
}
return tsc_overhead_serial / iterations;
}

View file

@ -0,0 +1,73 @@
/*
* =====================================================================================
*
* Filename: rdtsc.c
*
* Description:
*
* Version: 1.0
* Created: 24.01.2011 13:41:30
* Revision: none
* Compiler: gcc
*
* Author: Georg Wassen (gw) (),
* Company:
*
* =====================================================================================
*/
#ifndef RDTSC_H
#define RDTSC_H
#include <stdint.h>
/*
* rdtsc_ticks_per_sec(): measure frequency. Takes below a second.
*/
uint64_t rdtsc_ticks_per_sec(void) __attribute__((optimize(3)));
typedef union __attribute__((__transparent_union__))
{
uint64_t *__u64;
struct {uint32_t __low; uint32_t __high;} *__u32;
} tsc_t;
/*
* rdtsc(): Register-save version (compiler may insert additional push/pop)
* (clobbered-registers not given b/c compiler deduces from output-registers)
*/
static inline void __attribute__((__always_inline__, gnu_inline, optimize(3))) rdtsc(tsc_t tsc)
{
__asm__ volatile ("rdtsc" : "=a"(tsc.__u32->__low), "=d"(tsc.__u32->__high) );
}
/*
* rdtsc_serial(): get RDTSC with leading and rear serializing LFENCE instruction
*/
static inline void __attribute__((__always_inline__, gnu_inline, optimize(3))) rdtsc_serialized(tsc_t tsc)
{
#if ! __MIC__
__asm__ volatile (
"lfence\n\t" // serialize (needs SSE2, available since AMD Athlon64, Intel Core)
"rdtsc\n\t"
"lfence\n\t"
: "=a"(tsc.__u32->__low), "=d"(tsc.__u32->__high) );
#else
__asm__ volatile (
"lock; add $0, 0(%%rsp)\n\t" // serialize
"rdtsc\n\t"
"lock; add $0, 0(%%rsp)\n\t" // serialize
: "=a"(tsc.__u32->__low), "=d"(tsc.__u32->__high) :: "memory" );
#endif
}
void rdtsc_loop(uint64_t ticks);
void rdtsc_loop_sec(unsigned seconds);
uint64_t rdtsc_max_freq(int id);
int rdtsc_is_invariant(void);
uint64_t rdtsc_get_overhead(uint64_t iterations);
uint64_t rdtsc_get_overhead_serialized(uint64_t iterations);
#endif

View file

@ -0,0 +1,79 @@
/*
* =====================================================================================
*
* Filename: report.c
*
* Description:
*
* Version: 1.0
* Created: 25.07.2014 15:11:54
* Revision: none
* Compiler: gcc
*
* Author: Georg Wassen (gw) (),
* Company:
*
* =====================================================================================
*/
#include "report.h"
#include "hist.h"
#include <stdio.h>
int report_params(const struct opt *opt)
{
printf("init: tps = %llu\n", (unsigned long long)opt->tps);
printf("secs : %u\n", opt->secs);
printf("threshold : %llu\n", (unsigned long long)opt->threshold);
if (opt->mode == hist) {
printf("mode : histogram (cnt: %u, width: %u)\n", opt->hist_cnt, opt->hist_width);
} else if (opt->mode == list) {
printf("mode : list (cnt: %u)\n", opt->list_cnt);
}
return 0;
}
static int report_stat(const struct result *result)
{
printf(" # loops : %15llu\n",
(unsigned long long)result->cnt);
printf(" Min. : %15llu (@loop #%llu)\n",
(unsigned long long)result->min,
(unsigned long long)result->t_min);
printf(" Avg. : %18.2lf\n",
(double)result->sum/(double)result->cnt);
printf(" Max. : %15llu (@loop #%llu)\n",
(unsigned long long)result->max,
(unsigned long long)result->t_max);
return 0;
}
int report(const struct opt *opt, const struct result *result)
{
/*
* write results to stdout (or file)
* depending on opt
*/
printf("Dummy result: %llu \n", (unsigned long long)result->dummy);
report_stat(result);
if (opt->mode == hist) {
hist_print();
} else if (opt->mode == list) {
unsigned i;
for (i=0; i<opt->list_cnt; i++) {
if (result->list[i].time > 0) {
printf(" %15llu : %10llu\n",
(unsigned long long)result->list[i].time,
(unsigned long long)result->list[i].gap);
} else break;
}
}
return 0;
}

View file

@ -0,0 +1,28 @@
/*
* =====================================================================================
*
* Filename: report.h
*
* Description:
*
* Version: 1.0
* Created: 25.07.2014 15:11:07
* Revision: none
* Compiler: gcc
*
* Author: Georg Wassen (gw) (),
* Company:
*
* =====================================================================================
*/
#ifndef __REPORT_H__
#define __REPORT_H__
#include "run.h"
#include "opt.h"
int report_params(const struct opt *opt);
int report(const struct opt *opt, const struct result *result);
#endif // __REPORT_H__

161
hermit/usr/benchmarks/run.c Normal file
View file

@ -0,0 +1,161 @@
/*
* =====================================================================================
*
* Filename: run.c
*
* Description:
*
* Version: 1.0
* Created: 25.07.2014 15:10:30
* Revision: none
* Compiler: gcc
*
* Author: Georg Wassen (gw) (),
* Company:
*
* =====================================================================================
*/
#include "run.h"
#include "rdtsc.h"
#include "hist.h"
#include <limits.h>
#include <stdlib.h>
static struct result *results;
static const struct opt *opts;
static void store_results_stat(uint64_t gap, uint64_t offset)
{
if (gap < results->min) {
results->min = gap;
results->t_min = results->cnt;
}
if (gap > results->max) {
results->max = gap;
results->t_max = results->cnt;
}
results->sum += gap;
results->cnt++; /* avg = sum/cnt */
}
static void store_results_hist(uint64_t gap, uint64_t offset)
{
/*
* create histogram
*/
store_results_stat(gap, offset);
hist_add(gap);
}
static unsigned list_cnt;
static unsigned list_idx = 0;
static void store_results_list(uint64_t gap, uint64_t offset)
{
/*
* store all timestamps
*/
if (list_idx >= list_cnt) return;
store_results_stat(gap, offset);
results->list[list_idx].time = offset;
results->list[list_idx].gap = gap;
list_idx++;
}
static void (*store_results)(uint64_t gap, uint64_t offset);
static int reset_results(void)
{
results->min=UINT64_MAX;
results->max=0;
results->sum=0;
results->cnt=0;
results->t_min = 0;
results->t_max = 0;
if (opts->mode == hist) {
hist_reset();
} else if (opts->mode == list) {
unsigned i;
for (i=0; i<opts->list_cnt; i++) {
results->list[i].time=0;
results->list[i].gap=0;
}
list_idx = 0;
}
return 0;
}
static int hourglass(uint64_t duration, uint64_t threshold)
{
uint64_t t1, t2, t_end, diff; /* timestamps */
reset_results();
rdtsc(&t1); /* start-time */
t_end = t1 + duration; /* calculate end-time */
while (t1 < t_end) { /* loop until end-time */
t2 = t1;
rdtsc(&t1);
diff = t1 - t2;
if (diff > threshold) {
store_results(diff, t2);
}
/* Note: additional workload may be added here */
}
return 0;
}
int run(const struct opt *opt, struct result *result)
{
unsigned i;
results = result;
opts = opt;
results->hist = NULL;
switch (opt->mode) {
case stat :
store_results = store_results_stat;
break;
case hist :
store_results = store_results_hist;
results->hist = hist_alloc(opt);
hist_reset();
break;
case list :
store_results = store_results_list;
list_cnt = opt->list_cnt;
results->list = calloc(opt->list_cnt, sizeof(struct res_list));
for (i=0; i<opt->list_cnt; i++) {
results->list[i].time=0;
results->list[i].gap=0;
}
break;
}
/*
* execute hourglass routine
*/
hourglass(1 * opt->tps, opt->threshold); // 1 sec warmup
hourglass(opt->secs * opt->tps, opt->threshold);
return 0;
}
int run_free(const struct opt *opt, struct result *result)
{
if (results->hist != NULL) {
free(results->hist);
results->hist = NULL;
}
if (results->list != NULL) {
free(results->list);
results->list = NULL;
}
return 0;
}

View file

@ -0,0 +1,50 @@
/*
* =====================================================================================
*
* Filename: run.h
*
* Description:
*
* Version: 1.0
* Created: 25.07.2014 15:08:43
* Revision: none
* Compiler: gcc
*
* Author: Georg Wassen (gw) (),
* Company:
*
* =====================================================================================
*/
#ifndef __RUN_H__
#define __RUN_H__
#include "opt.h"
#include <stdint.h>
struct res_list {
uint64_t time;
uint64_t gap;
};
struct result {
uint64_t dummy;
uint64_t min;
uint64_t max;
uint64_t sum;
uint64_t cnt;
uint64_t t_min;
uint64_t t_max;
uint32_t *hist;
struct res_list *list;
};
int run(const struct opt *opt, struct result *result);
int run_free(const struct opt *opt, struct result *result);
#endif // __RUN_H__

View file

@ -0,0 +1,40 @@
/*
* =====================================================================================
*
* Filename: setup.c
*
* Description:
*
* Version: 1.0
* Created: 25.07.2014 15:07:43
* Revision: none
* Compiler: gcc
*
* Author: Georg Wassen (gw) (),
* Company:
*
* =====================================================================================
*/
#include "setup.h"
int setup(struct opt *opt)
{
/*
* set up run-time environment for benchmark
* depending on opt
* e.g. create cpu-set, move IRQs, etc.
*/
return 0;
}
int setdown(struct opt *opt)
{
/*
* undo things from setup()
*/
return 0;
}

View file

@ -0,0 +1,27 @@
/*
* =====================================================================================
*
* Filename: setup.h
*
* Description:
*
* Version: 1.0
* Created: 25.07.2014 15:06:59
* Revision: none
* Compiler: gcc
*
* Author: Georg Wassen (gw) (),
* Company:
*
* =====================================================================================
*/
#ifndef __SETUP_H__
#define __SETUP_H__
#include "opt.h"
int setup(struct opt *opt);
int setdown(struct opt *opt);
#endif // __SETUP_H__