From 515e5a30e2ec2d42fe7c85dcc267242af2f4f8ab Mon Sep 17 00:00:00 2001 From: Akilan Date: Thu, 7 Nov 2024 17:09:42 +0000 Subject: [PATCH] added more benchmarks --- .../benchmarks/StressTestMalloc/glibc-bench.c | 5 + .../StressTestMalloc/glibc-bench.sh | 2 + .../benchmarks/StressTestMalloc/loadmem.c | 75 ++- .../StressTestMalloc/memaccesstest.c | 6 +- .../StressTestMalloc/memaccesstest.sh | 2 + .../StressTestMalloc/run-loadmem.sh | 2 + .../benchmarks/matrix_multiply/build.sh | 8 +- .../matrix_multiply/matrix_multiply-pthread.c | 8 +- .../benchmarks/matrix_multiply/stddefines.h | 65 ++- .../matrix_multiply_cache_tuned/build.sh | 3 +- .../benchmarks/richards-benchmark/benchmark.c | 447 ++++++++++++++++++ .../benchmarks/richards-benchmark/build.sh | 2 + .../benchmarks/richards-benchmark/harness.h | 36 ++ .../richards-benchmark/stddefines.h | 298 ++++++++++++ 14 files changed, 926 insertions(+), 33 deletions(-) create mode 100644 benchmarks/benchmarks/StressTestMalloc/glibc-bench.sh create mode 100644 benchmarks/benchmarks/StressTestMalloc/memaccesstest.sh create mode 100644 benchmarks/benchmarks/StressTestMalloc/run-loadmem.sh create mode 100644 benchmarks/benchmarks/richards-benchmark/benchmark.c create mode 100644 benchmarks/benchmarks/richards-benchmark/build.sh create mode 100644 benchmarks/benchmarks/richards-benchmark/harness.h create mode 100644 benchmarks/benchmarks/richards-benchmark/stddefines.h diff --git a/benchmarks/benchmarks/StressTestMalloc/glibc-bench.c b/benchmarks/benchmarks/StressTestMalloc/glibc-bench.c index d40b131..5c603f0 100644 --- a/benchmarks/benchmarks/StressTestMalloc/glibc-bench.c +++ b/benchmarks/benchmarks/StressTestMalloc/glibc-bench.c @@ -23,6 +23,10 @@ #include #include #include "malloc.h" + +#define malloc MALLOCCHERI +#define free FREECHERI + // #include "bench-timing.h" // #include "json-lib.h" @@ -193,6 +197,7 @@ static void usage (const char *name) int main (int argc, char **argv) { + INITREGULARALLOC(); long size = 16; if (argc == 2) size = strtol (argv[1], NULL, 0); diff --git a/benchmarks/benchmarks/StressTestMalloc/glibc-bench.sh b/benchmarks/benchmarks/StressTestMalloc/glibc-bench.sh new file mode 100644 index 0000000..5135664 --- /dev/null +++ b/benchmarks/benchmarks/StressTestMalloc/glibc-bench.sh @@ -0,0 +1,2 @@ +sh build.sh +time pmcstat -d -w 1 -p l1d_tlb_rd -p l2d_tlb_rd -p l1d_tlb_refill -p cpu_cycles -p dtlb_walk -p stall_backend -p ll_cache_miss_rd -o glibc-cheri.stat ./glibc-bench.out \ No newline at end of file diff --git a/benchmarks/benchmarks/StressTestMalloc/loadmem.c b/benchmarks/benchmarks/StressTestMalloc/loadmem.c index 82c2a4d..54326e7 100644 --- a/benchmarks/benchmarks/StressTestMalloc/loadmem.c +++ b/benchmarks/benchmarks/StressTestMalloc/loadmem.c @@ -2,25 +2,60 @@ #include #include "malloc.h" -int main(){ - int *ptr; - unsigned long i,n; - printf("Enter number of int(4 byte) you want to allocate:"); - scanf("%lu",&n); +#define malloc MALLOCCHERI +#define free FREECHERI + +// performing various sizes of mallocs are free +void +bench (unsigned long n) { + int *ptr; + unsigned long i; + // printf("Enter number of int(4 byte) you want to allocate:"); - printf("Allocating %lu bytes......\n",n*sizeof(int)); - ptr=(int*)malloc(n*sizeof(int)); - if (ptr==NULL){ - printf("ERROR!Memory not allocated!"); - exit(0); - } - printf("Filling int into memory.....\n"); - for (i = 0; i < n; i++){ - ptr[i] = 1; - } - printf("Sleep 10 seconds......\n"); - sleep(10); - printf("Free memory.\n"); - free(ptr); - return 0; + printf("Allocating %lu bytes......\n",n*sizeof(int)); + ptr=(int*)malloc(n*sizeof(int)); + if (ptr==NULL){ + printf("ERROR!Memory not allocated!"); + exit(0); + } + printf("Filling int into memory.....\n"); + for (i = 0; i < n; i++){ + ptr[i] = 1; + } + printf("Sleep 10 seconds......\n"); + sleep(10); + printf("Free memory.\n"); + free(ptr); +} + +int main(){ + + INITREGULARALLOC(); + bench(8); + bench(30); + bench(100); + bench(600); + bench(1000); + bench(7000); + +// int *ptr; +// unsigned long i,n; +// printf("Enter number of int(4 byte) you want to allocate:"); +// scanf("%lu",&n); + +// printf("Allocating %lu bytes......\n",n*sizeof(int)); +// ptr=(int*)malloc(n*sizeof(int)); +// if (ptr==NULL){ +// printf("ERROR!Memory not allocated!"); +// exit(0); +// } +// printf("Filling int into memory.....\n"); +// for (i = 0; i < n; i++){ +// ptr[i] = 1; +// } +// printf("Sleep 10 seconds......\n"); +// sleep(10); +// printf("Free memory.\n"); +// free(ptr); +// return 0; } \ No newline at end of file diff --git a/benchmarks/benchmarks/StressTestMalloc/memaccesstest.c b/benchmarks/benchmarks/StressTestMalloc/memaccesstest.c index 265818d..481191b 100644 --- a/benchmarks/benchmarks/StressTestMalloc/memaccesstest.c +++ b/benchmarks/benchmarks/StressTestMalloc/memaccesstest.c @@ -20,6 +20,9 @@ All rights reserved. #include "malloc.h" +#define malloc MALLOCCHERI +#define free FREECHERI + struct l{ @@ -263,6 +266,7 @@ void * walk(void *param) int main(int argc,char **argv) { +INITREGULARALLOC(); #ifdef DEBUG printf("DEBUG:sizeof(struct l)=%ld\n",sizeof(struct l)); #endif @@ -273,7 +277,7 @@ int main(int argc,char **argv) pthread_t threads[NTHREADS]; - root=calloc(MAX_WSS/sizeof(struct l),sizeof(struct l)); + root=malloc(MAX_WSS/sizeof(struct l) * sizeof(struct l)); for(working_set_size=MIN_WSS;working_set_size matrix_multiply_200_mmap_out.txt +time pmcstat -d -w 1 -p l1d_tlb_rd -p l2d_tlb_rd -p l1d_tlb_refill -p cpu_cycles -p dtlb_walk -p stall_backend -p ll_cache_miss_rd -o matrix_multiply_regular_200.txt ./matrix_multiply-pthread.out 200 -create_files > matrix_multiply_200_regular_out.txt # Run multiple PMCStat paramters # sudo pmcstat -d -w 1 -p ll_cache_miss_rd ./matrix_multiply-pthread.out 200 -create_files > test.out # sudo pmcstat -d -w 1 -p L2D_TLB ./matrix_multiply-pthread.out 200 -create_files > test.out @@ -9,9 +9,9 @@ sudo time pmcstat -d -w 1 -p l1d_tlb_rd -p l2d_tlb_rd -p l1d_tlb_refill -p cpu_c # sudo pmcstat -d -w 1 -p L1D_TLB_RD ./matrix_multiply-pthread.out 200 -create_files > test.out # sudo pmcstat -d -w 1 -p L2D_TLB ./matrix_multiply-pthread.out 200 -create_files > test.out -sudo time pmcstat -d -w 1 -p l1d_tlb_rd -p l2d_tlb_rd -p l1d_tlb_refill -p cpu_cycles -p dtlb_walk -p stall_backend -p ll_cache_miss_rd -o matrix_multiply_mmap_1000.txt ./matrix_multiply-pthread.out 1000 -create_files > matrix_multiply_1000_mmap_out.txt +time pmcstat -d -w 1 -p l1d_tlb_rd -p l2d_tlb_rd -p l1d_tlb_refill -p cpu_cycles -p dtlb_walk -p stall_backend -p ll_cache_miss_rd -o matrix_multiply_regular_1000.txt ./matrix_multiply-pthread.out 1000 -create_files > matrix_multiply_1000_regular_out.txt -sudo time pmcstat -d -w 1 -p l1d_tlb_rd -p l2d_tlb_rd -p l1d_tlb_refill -p cpu_cycles -p dtlb_walk -p stall_backend -p ll_cache_miss_rd -o matrix_multiply_mmap_3000.txt ./matrix_multiply-pthread.out 3000 -create_files > matrix_multiply_3000_mmap_out.txt +time pmcstat -d -w 1 -p l1d_tlb_rd -p l2d_tlb_rd -p l1d_tlb_refill -p cpu_cycles -p dtlb_walk -p stall_backend -p ll_cache_miss_rd -o matrix_multiply_regular_3000.txt ./matrix_multiply-pthread.out 3000 -create_files > matrix_multiply_3000_regular_out.txt # sudo pmcstat -d -w 1 -p ll_cache_miss_rd ./matrix_multiply-pthread.out 1000 -create_files > test.out # sudo pmcstat -d -w 1 -p L2D_TLB ./matrix_multiply-pthread.out 1000 -create_files > test.out diff --git a/benchmarks/benchmarks/matrix_multiply/matrix_multiply-pthread.c b/benchmarks/benchmarks/matrix_multiply/matrix_multiply-pthread.c index d12233f..9b215cb 100644 --- a/benchmarks/benchmarks/matrix_multiply/matrix_multiply-pthread.c +++ b/benchmarks/benchmarks/matrix_multiply/matrix_multiply-pthread.c @@ -45,8 +45,8 @@ #include "coz.h" -#define malloc MALLOCCHERI -#define free FREECHERI +// #define malloc MALLOCCHERI +// #define free FREECHERI typedef struct { int row_num; @@ -173,8 +173,8 @@ void *matrixmult_map(void *args_in) int main(int argc, char *argv[]) { - INITAlloc(); -// INITREGULARALLOC(); + //INITAlloc(); + //INITREGULARALLOC(); int i,j, create_files; int fd_A, fd_B, fd_out,file_size; diff --git a/benchmarks/benchmarks/matrix_multiply/stddefines.h b/benchmarks/benchmarks/matrix_multiply/stddefines.h index b7d586e..595bdcb 100644 --- a/benchmarks/benchmarks/matrix_multiply/stddefines.h +++ b/benchmarks/benchmarks/matrix_multiply/stddefines.h @@ -30,13 +30,17 @@ #include #include #include +#include #include #include +#include + #include #include #include #include +#include #include #include @@ -44,6 +48,8 @@ #include #include +#define MAXPAGESIZES 2 + //#define TIMING @@ -207,13 +213,68 @@ void FREECHERI(void *ptr) { munmap(ptr, len); } +static int +pagesizes(size_t ps[MAXPAGESIZES]) +{ + int pscnt; + + pscnt = getpagesizes(ps, MAXPAGESIZES); + // ATF_REQUIRE_MSG(pscnt != -1, "getpagesizes failed; errno=%d", errno); + // ATF_REQUIRE_MSG(ps[0] != 0, "psind 0 is %zu", ps[0]); + // ATF_REQUIRE_MSG(pscnt <= MAXPAGESIZES, "invalid pscnt %d", pscnt); + // if (pscnt == 1){ + // printf("pscnt is 1"); + // } + + // atf_tc_skip("no large page support"); + return (pscnt); +} + INITREGULARALLOC(void) { size_t sz; // Pre Allocate 400 MB - sz = 100000000; + sz = 1073741824; + + int error, fd, pscnt, pn; + + size_t ps[MAXPAGESIZES]; + + size_t size[3]; + + pn = getpagesizes(size, 3); + printf("page size is [%d]", size[2]); + + pscnt = pagesizes(ps); + + fd = shm_create_largepage(SHM_ANON, O_CREAT | O_RDWR, 1, SHM_LARGEPAGE_ALLOC_DEFAULT, 0); + + if (fd < 0 && errno == ENOTTY) { + perror("sh_create_largepages"); + close(fd); + exit(EXIT_FAILURE); + } + // if (fd < 0) + // perror("no large page supported"); + // exit(EXIT_FAILURE); + // if (fd < 0 && errno == ENOTTY) + // atf_tc_skip("no large page support"); + // ATF_REQUIRE_MSG(fd >= 0, "shm_create_largepage failed; errno=%d", errno); + + if (ftruncate(fd, sz) < 0) { + perror("ftruncate"); + close(fd); + exit(EXIT_FAILURE); + } + // if (error != 0 && errno == ENOMEM) + // /* + // * The test system might not have enough memory to accommodate + // * the request. + // */ + // atf_tc_skip("failed to allocate %zu-byte superpage", sz); + // ATF_REQUIRE_MSG(error == 0, "ftruncate failed; errno=%d", errno); ptr = mmap(NULL, sz, - PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON,-1,0); + PROT_READ|PROT_WRITE, MAP_SHARED,fd,0); // Added error handling if(ptr == MAP_FAILED) diff --git a/benchmarks/benchmarks/matrix_multiply_cache_tuned/build.sh b/benchmarks/benchmarks/matrix_multiply_cache_tuned/build.sh index 8c03368..0ce299c 100644 --- a/benchmarks/benchmarks/matrix_multiply_cache_tuned/build.sh +++ b/benchmarks/benchmarks/matrix_multiply_cache_tuned/build.sh @@ -1,3 +1,2 @@ -git pull origin main cc -g -Wall -o matrix_multiply.out -mabi=purecap-benchmark -lpthread matrix_multiply.c -sudo pmcstat -d -w 1 -p ll_cache_miss_rd ./matrix_multiply.out +pmcstat -d -w 1 -p ll_cache_miss_rd ./matrix_multiply.out diff --git a/benchmarks/benchmarks/richards-benchmark/benchmark.c b/benchmarks/benchmarks/richards-benchmark/benchmark.c new file mode 100644 index 0000000..51ef20e --- /dev/null +++ b/benchmarks/benchmarks/richards-benchmark/benchmark.c @@ -0,0 +1,447 @@ +// clang-format off + +/* C version of the systems programming language benchmark +** Author: M. J. Jordan Cambridge Computer Laboratory. +** +** Modified by: M. Richards, Nov 1996 +** to be ANSI C and runnable on 64 bit machines + other minor changes +** Modified by: M. Richards, 20 Oct 1998 +** made minor corrections to improve ANSI compliance (suggested +** by David Levine) +** Modified by: Jeremy Singer, 25 May 2022 +** adapted to use uintptr_t for compatibility with architectures +** that do not have word-sized pointers (e.g. CHERI) +** also adapted to use Boehm-Demers-Weiser GC instead of system +** malloc, when compiled with -DGC +** +** Compile with, say +** +** gcc -o bench bench.c +** +** or +** +** gcc -o bench100 -Dbench100 bench.c (for a version that obeys +** the main loop 100x more often) +*/ + +#include +#include +#include + +#include "harness.h" +#include "stddefines.h" + +// #ifdef GC +// #include "gc.h" +// #define MALLOC GC_MALLOC +// #else +// #define MALLOC malloc +// #endif // GC + +// #define MALLOC MALLOCCHERI +// #define free FREECHERI + +#ifdef bench100 +#define Count 10000*100 +#define Qpktcountval 2326410 +#define Holdcountval 930563 +#else +#define Count 10000 +#define Qpktcountval 23246 +#define Holdcountval 9297 +#endif + +#define TRUE 1 +#define FALSE 0 +#define MAXINT 32767 + +#define BUFSIZE 3 +#define I_IDLE 1 +#define I_WORK 2 +#define I_HANDLERA 3 +#define I_HANDLERB 4 +#define I_DEVA 5 +#define I_DEVB 6 +#define PKTBIT 1 +#define WAITBIT 2 +#define HOLDBIT 4 +#define NOTPKTBIT !1 +#define NOTWAITBIT !2 +#define NOTHOLDBIT 0XFFFB + +#define S_RUN 0 +#define S_RUNPKT 1 +#define S_WAIT 2 +#define S_WAITPKT 3 +#define S_HOLD 4 +#define S_HOLDPKT 5 +#define S_HOLDWAIT 6 +#define S_HOLDWAITPKT 7 + +#define K_DEV 1000 +#define K_WORK 1001 + +struct packet +{ + struct packet *p_link; + int p_id; + int p_kind; + int p_a1; + char p_a2[BUFSIZE+1]; +}; + +struct task +{ + struct task *t_link; + int t_id; + int t_pri; + struct packet *t_wkq; + int t_state; + struct task *(*t_fn)(struct packet *); + uintptr_t t_v1; + uintptr_t t_v2; +}; + +char alphabet[28] = "0ABCDEFGHIJKLMNOPQRSTUVWXYZ"; +struct task *tasktab[11] = {(struct task *)10,0,0,0,0,0,0,0,0,0,0}; +struct task *tasklist = 0; +struct task *tcb; +long taskid; +uintptr_t v1; +uintptr_t v2; +int qpktcount = 0; +int holdcount = 0; +int tracing = 0; +int layout = 0; + +void append(struct packet *pkt, struct packet *ptr); + +void createtask(int id, + int pri, + struct packet *wkq, + int state, + struct task *(*fn)(struct packet *), + uintptr_t v1, + uintptr_t v2) +{ + struct task *t = (struct task *)MALLOC(sizeof(struct task)); + + tasktab[id] = t; + t->t_link = tasklist; + t->t_id = id; + t->t_pri = pri; + t->t_wkq = wkq; + t->t_state = state; + t->t_fn = fn; + t->t_v1 = v1; + t->t_v2 = v2; + tasklist = t; +} + +struct packet *pkt(struct packet *link, int id, int kind) +{ + int i; + struct packet *p = (struct packet *)MALLOC(sizeof(struct packet)); + + for (i=0; i<=BUFSIZE; i++) + p->p_a2[i] = 0; + + p->p_link = link; + p->p_id = id; + p->p_kind = kind; + p->p_a1 = 0; + + return (p); +} + +void trace(char a) +{ + if ( --layout <= 0 ) + { + printf("\n"); + layout = 50; + } + + printf("%c", a); +} + +void schedule() +{ + while ( tcb != 0 ) + { + struct packet *pkt; + struct task *newtcb; + + pkt=0; + + switch ( tcb->t_state ) + { + case S_WAITPKT: + pkt = tcb->t_wkq; + tcb->t_wkq = pkt->p_link; + tcb->t_state = tcb->t_wkq == 0 ? S_RUN : S_RUNPKT; + + case S_RUN: + case S_RUNPKT: + taskid = tcb->t_id; + v1 = tcb->t_v1; + v2 = tcb->t_v2; + if (tracing) { + trace(taskid+'0'); + } + newtcb = (*(tcb->t_fn))(pkt); + tcb->t_v1 = v1; + tcb->t_v2 = v2; + tcb = newtcb; + break; + + case S_WAIT: + case S_HOLD: + case S_HOLDPKT: + case S_HOLDWAIT: + case S_HOLDWAITPKT: + tcb = tcb->t_link; + break; + + default: + return; + } + } +} + +struct task *wait_task(void) +{ + tcb->t_state |= WAITBIT; + return (tcb); +} + +struct task *holdself(void) +{ + ++holdcount; + tcb->t_state |= HOLDBIT; + return (tcb->t_link) ; +} + +struct task *findtcb(int id) +{ + struct task *t = 0; + + if (1<=id && id<=(long)tasktab[0]) + t = tasktab[id]; + if (t==0) printf("\nBad task id %d\n", id); + return(t); +} + +struct task *release(int id) +{ + struct task *t; + + t = findtcb(id); + if ( t==0 ) return (0); + + t->t_state &= NOTHOLDBIT; + if ( t->t_pri > tcb->t_pri ) return (t); + + return (tcb) ; +} + + +struct task *qpkt(struct packet *pkt) +{ + struct task *t; + + t = findtcb(pkt->p_id); + if (t==0) return (t); + + qpktcount++; + + pkt->p_link = 0; + pkt->p_id = taskid; + + if (t->t_wkq==0) + { + t->t_wkq = pkt; + t->t_state |= PKTBIT; + if (t->t_pri > tcb->t_pri) return (t); + } + else + { + append(pkt, (struct packet *)&(t->t_wkq)); + } + + return (tcb); +} + +struct task *idlefn(struct packet *pkt) +{ + if ( --v2==0 ) return ( holdself() ); + + if ( (v1&1) == 0 ) + { + v1 = ( v1>>1) & MAXINT; + return ( release(I_DEVA) ); + } + else + { + v1 = ( (v1>>1) & MAXINT) ^ 0XD008; + return ( release(I_DEVB) ); + } +} + +struct task *workfn(struct packet *pkt) +{ + if ( pkt==0 ) return ( wait_task() ); + else + { + int i; + + v1 = I_HANDLERA + I_HANDLERB - v1; + pkt->p_id = v1; + + pkt->p_a1 = 0; + for (i=0; i<=BUFSIZE; i++) + { + v2++; + if ( v2 > 26 ) v2 = 1; + (pkt->p_a2)[i] = alphabet[v2]; + } + return ( qpkt(pkt) ); + } +} + +struct task *handlerfn(struct packet *pkt) +{ + if ( pkt!=0) { + append(pkt, (struct packet *)(pkt->p_kind==K_WORK ? &v1 : &v2)); + } + + if ( v1!=0 ) { + int count; + struct packet *workpkt = (struct packet *)v1; + count = workpkt->p_a1; + + if ( count > BUFSIZE ) { + v1 = (uintptr_t)(((struct packet *)v1)->p_link); + return ( qpkt(workpkt) ); + } + + if ( v2!=0 ) { + struct packet *devpkt; + + devpkt = (struct packet *)v2; + v2 = (uintptr_t)(((struct packet *)v2)->p_link); + devpkt->p_a1 = workpkt->p_a2[count]; + workpkt->p_a1 = count+1; + return( qpkt(devpkt) ); + } + } + return wait_task(); +} + +struct task *devfn(struct packet *pkt) +{ + if ( pkt==0 ) + { + if ( v1==0 ) return ( wait_task() ); + pkt = (struct packet *)v1; + v1 = 0; + return ( qpkt(pkt) ); + } + else + { + v1 = (uintptr_t)pkt; + if (tracing) trace(pkt->p_a1); + return ( holdself() ); + } +} + +void append(struct packet *pkt, struct packet *ptr) +{ + pkt->p_link = 0; + + while ( ptr->p_link ) ptr = ptr->p_link; + + ptr->p_link = pkt; +} + +int bench() { + struct packet *wkq = 0; + + // printf("Bench mark starting\n"); + + createtask(I_IDLE, 0, wkq, S_RUN, idlefn, 1, Count); + + wkq = pkt(0, 0, K_WORK); + wkq = pkt(wkq, 0, K_WORK); + + createtask(I_WORK, 1000, wkq, S_WAITPKT, workfn, I_HANDLERA, 0); + + wkq = pkt(0, I_DEVA, K_DEV); + wkq = pkt(wkq, I_DEVA, K_DEV); + wkq = pkt(wkq, I_DEVA, K_DEV); + + createtask(I_HANDLERA, 2000, wkq, S_WAITPKT, handlerfn, 0, 0); + + wkq = pkt(0, I_DEVB, K_DEV); + wkq = pkt(wkq, I_DEVB, K_DEV); + wkq = pkt(wkq, I_DEVB, K_DEV); + + createtask(I_HANDLERB, 3000, wkq, S_WAITPKT, handlerfn, 0, 0); + + wkq = 0; + createtask(I_DEVA, 4000, wkq, S_WAIT, devfn, 0, 0); + createtask(I_DEVB, 5000, wkq, S_WAIT, devfn, 0, 0); + + tcb = tasklist; + + qpktcount = holdcount = 0; + + // printf("Starting\n"); + + tracing = FALSE; + layout = 0; + + schedule(); + + // printf("\nfinished\n"); + + + + + if (!(qpktcount == Qpktcountval && holdcount == Holdcountval)) { + printf("qpkt count = %d holdcount = %d\n", qpktcount, holdcount); + printf("These results are incorrect"); + exit(1); + } + // printf("\nend of run\n"); + return qpktcount; +} + + +int inner_loop(int inner) { + int r = 0; + while (inner > 0) { + r += bench(); + inner--; + } + return r; +} + +int main(int argc, char* argv[]) +{ + //INITREGULARALLOC(); + int iterations = 100; + int warmup = 0; + int inner_iterations = 100; + + parse_argv(argc, argv, &iterations, &warmup, &inner_iterations); + + int result = 0; + while (iterations > 0) { + unsigned long start = microseconds(); + result += inner_loop(inner_iterations); + unsigned long elapsed = microseconds() - start; + printf("Richards: iterations=1 runtime: %lu%s\n", elapsed, "us"); + iterations--; + } +} \ No newline at end of file diff --git a/benchmarks/benchmarks/richards-benchmark/build.sh b/benchmarks/benchmarks/richards-benchmark/build.sh new file mode 100644 index 0000000..2a73008 --- /dev/null +++ b/benchmarks/benchmarks/richards-benchmark/build.sh @@ -0,0 +1,2 @@ +cc -g -Wall -o benchmark.out -mabi=purecap-benchmark -lpthread benchmark.c +time pmcstat -d -w 1 -p l1d_tlb_rd -p l2d_tlb_rd -p l1d_tlb_refill -p cpu_cycles -p dtlb_walk -p stall_backend -p ll_cache_miss_rd -o benchmark-regular.txt ./benchmark.out > benchmark-regular-out.txt \ No newline at end of file diff --git a/benchmarks/benchmarks/richards-benchmark/harness.h b/benchmarks/benchmarks/richards-benchmark/harness.h new file mode 100644 index 0000000..d3080b7 --- /dev/null +++ b/benchmarks/benchmarks/richards-benchmark/harness.h @@ -0,0 +1,36 @@ +// clang-format off + +/** A simple harness for the C benchmarks + * + * It is included by every benchmark file and provides the time measuring, + * as well as standardized command-line argument parsing. + */ + +#include + +unsigned long microseconds() { + // Not monotonic + struct timeval t; + gettimeofday(&t, NULL); + return (t.tv_sec * 1000 * 1000) + t.tv_usec; +}; + +void parse_argv(int argc, + char** argv, + int* iterations, + int* warmup, + int* inner_or_problem_size) { + if (argc > 1) { + *iterations = atoi(argv[1]); + } + if (argc > 2) { + *warmup = atoi(argv[2]); + } + if (argc > 3) { + *inner_or_problem_size = atoi(argv[3]); + } + + printf("Overall iterations: %d\n", *iterations); + printf("Warmup iterations: %d\n", *warmup); + printf("Inner it./problem size: %d\n", *inner_or_problem_size); +}; \ No newline at end of file diff --git a/benchmarks/benchmarks/richards-benchmark/stddefines.h b/benchmarks/benchmarks/richards-benchmark/stddefines.h new file mode 100644 index 0000000..595bdcb --- /dev/null +++ b/benchmarks/benchmarks/richards-benchmark/stddefines.h @@ -0,0 +1,298 @@ +/* Copyright (c) 2007-2009, Stanford University +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* * Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* * 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. +* * Neither the name of Stanford University nor the +* names of its contributors may be used to endorse or promote products +* derived from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY STANFORD UNIVERSITY ``AS IS'' AND ANY +* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +* DISCLAIMED. IN NO EVENT SHALL STANFORD UNIVERSITY BE LIABLE FOR ANY +* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef STDDEFINES_H_ +#define STDDEFINES_H_ + +#include +#include +#include +#include +#include +#include +#include + + +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +#define MAXPAGESIZES 2 + + +//#define TIMING + +/* Debug printf */ +#define dprintf(...) fprintf(stdout, __VA_ARGS__) + +/* Wrapper to check for errors */ +#define CHECK_ERROR(a) \ + if (a) \ + { \ + perror("Error at line\n\t" #a "\nSystem Msg"); \ + assert ((a) == 0); \ + } + +static inline void *MALLOC(size_t size) +{ + void * temp = malloc(size); + assert(temp); + return temp; +} + +static inline void *CALLOC(size_t num, size_t size) +{ + void * temp = calloc(num, size); + assert(temp); + return temp; +} + +static inline void *REALLOC(void *ptr, size_t size) +{ + void * temp = realloc(ptr, size); + assert(temp); + return temp; +} + +static inline char *GETENV(char *envstr) +{ + char *env = getenv(envstr); + if (!env) return "0"; + else return env; +} + +#define GET_TIME(start, end, duration) \ + duration.tv_sec = (end.tv_sec - start.tv_sec); \ + if (end.tv_nsec >= start.tv_nsec) { \ + duration.tv_nsec = (end.tv_nsec - start.tv_nsec); \ + } \ + else { \ + duration.tv_nsec = (1000000000L - (start.tv_nsec - end.tv_nsec)); \ + duration.tv_sec--; \ + } \ + if (duration.tv_nsec >= 1000000000L) { \ + duration.tv_sec++; \ + duration.tv_nsec -= 1000000000L; \ + } + +static inline unsigned int time_diff ( + struct timeval *end, struct timeval *begin) +{ +#ifdef TIMING + uint64_t result; + + result = end->tv_sec - begin->tv_sec; + result *= 1000000; /* usec */ + result += end->tv_usec - begin->tv_usec; + + return result; +#else + return 0; +#endif +} + +static inline void get_time (struct timeval *t) +{ +#ifdef TIMING + gettimeofday (t, NULL); +#endif +} + +// Expirement work + +#define FILENAME "/dev/contigmem" + +static char *heap_start; +static char *heap; +static size_t HEAP_SIZE = 1024 * 1024 * 1024; + +void *ptr; +int MallocCounter; + +size_t sizeUsed; + +INITAlloc(void) { + + size_t sz; + // Pre Allocate 600 MB + sz = 100000000; + + int fd = open(FILENAME, O_RDWR, 0600); + + if (fd < 0) { + perror("open"); + exit(EXIT_FAILURE); + } + + off_t offset = 0; // offset to seek to. + + if (ftruncate(fd, sz) < 0) { + perror("ftruncate"); + close(fd); + exit(EXIT_FAILURE); + } + + // ptr = mmap(NULL, sz, + // PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON,-1,0); + + ptr = mmap(NULL, sz, + PROT_READ|PROT_WRITE, MAP_SHARED,fd,0); + + // Added error handling + if(ptr == MAP_FAILED) + { + perror("mmap"); + exit(EXIT_FAILURE); + } + + MallocCounter = (int)sz; + +} + +// Quick malloc implementation with mmap +void* MALLOCCHERI(size_t sz) +{ + sz = __builtin_align_up(sz, _Alignof(max_align_t)); + + // printf("%d \n", sz); + // printf("%d Malloc counter\n", MallocCounter); + + MallocCounter -= sz; + void *ptrLink = &ptr[MallocCounter]; + ptrLink = cheri_setbounds(ptrLink, sz); + + return ptrLink; + +// if (heap + sz > heap_start + HEAP_SIZE) return NULL; +// heap += sz; +// return heap - sz; + +} + +// Quick cheri free implementation +void FREECHERI(void *ptr) { + + // printf("free called \n"); + + // get bounds from + int len = cheri_getlen(ptr); + + // printf("free len %d \n", len); + + munmap(ptr, len); +} + +static int +pagesizes(size_t ps[MAXPAGESIZES]) +{ + int pscnt; + + pscnt = getpagesizes(ps, MAXPAGESIZES); + // ATF_REQUIRE_MSG(pscnt != -1, "getpagesizes failed; errno=%d", errno); + // ATF_REQUIRE_MSG(ps[0] != 0, "psind 0 is %zu", ps[0]); + // ATF_REQUIRE_MSG(pscnt <= MAXPAGESIZES, "invalid pscnt %d", pscnt); + // if (pscnt == 1){ + // printf("pscnt is 1"); + // } + + // atf_tc_skip("no large page support"); + return (pscnt); +} + +INITREGULARALLOC(void) { + size_t sz; + // Pre Allocate 400 MB + sz = 1073741824; + + int error, fd, pscnt, pn; + + size_t ps[MAXPAGESIZES]; + + size_t size[3]; + + pn = getpagesizes(size, 3); + printf("page size is [%d]", size[2]); + + pscnt = pagesizes(ps); + + fd = shm_create_largepage(SHM_ANON, O_CREAT | O_RDWR, 1, SHM_LARGEPAGE_ALLOC_DEFAULT, 0); + + if (fd < 0 && errno == ENOTTY) { + perror("sh_create_largepages"); + close(fd); + exit(EXIT_FAILURE); + } + // if (fd < 0) + // perror("no large page supported"); + // exit(EXIT_FAILURE); + // if (fd < 0 && errno == ENOTTY) + // atf_tc_skip("no large page support"); + // ATF_REQUIRE_MSG(fd >= 0, "shm_create_largepage failed; errno=%d", errno); + + if (ftruncate(fd, sz) < 0) { + perror("ftruncate"); + close(fd); + exit(EXIT_FAILURE); + } + // if (error != 0 && errno == ENOMEM) + // /* + // * The test system might not have enough memory to accommodate + // * the request. + // */ + // atf_tc_skip("failed to allocate %zu-byte superpage", sz); + // ATF_REQUIRE_MSG(error == 0, "ftruncate failed; errno=%d", errno); + + ptr = mmap(NULL, sz, + PROT_READ|PROT_WRITE, MAP_SHARED,fd,0); + + // Added error handling + if(ptr == MAP_FAILED) + { + perror("mmap"); + exit(EXIT_FAILURE); + } + + MallocCounter = (int)sz; +} +// Standard Alloc +// void* MALLOCREGULAR(size_t sz) { + +// } + + +// void* CLEARALLOC(void) { +// / +// } + +#endif // STDDEFINES_H_