added evaluation docs

This commit is contained in:
2025-01-09 23:40:50 +00:00
parent 5b5359feb1
commit b3c0b08a64
30 changed files with 1456 additions and 628 deletions

View File

@@ -54,7 +54,8 @@
"limits": "cpp",
"ratio": "cpp",
"tuple": "cpp",
"variant": "cpp"
"variant": "cpp",
"stddef.h": "c"
},
"C_Cpp.errorSquiggles": "disabled"
}

View File

@@ -10,10 +10,10 @@
#define malloc MALLOCCHERI
#define free FREECHERI
int main( int argc, char* argv[] )
int main(int argc, char* argv[] )
{
// Init alloc
INITREGULARALLOC();
// INITREGULARALLOC(0);
// =====================================================================
// Initialization & Command Line Read-In
// =====================================================================

View File

@@ -270,7 +270,7 @@ Inputs read_CLI( int argc, char * argv[] )
printf(" %d ", 6 * sizeof(char));
INITREGULARALLOC();
// INITREGULARALLOC();
// defaults to H-M Large benchmark
input.HM = (char *) malloc( 6 * sizeof(char) );

View File

@@ -1,298 +1,346 @@
/* 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.
*/
// /* 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_
// #ifndef STDDEFINES_H_
// #define STDDEFINES_H_
#include <assert.h>
#include <stdlib.h>
#include <sys/time.h>
#include <sys/errno.h>
#include <stdint.h>
#include <stdio.h>
#include <unistd.h>
// #include <assert.h>
// #include <stdlib.h>
// #include <sys/time.h>
// #include <sys/errno.h>
// #include <stdint.h>
// #include <stdio.h>
// // #include <unistd.h>
// #include <stddef.h>
// #include <stdlib.h>
// #include <string.h>
// #include <sys/mman.h>
// #include <sys/types.h>
// #include <cheriintrin.h>
// #include <cheri/cheric.h>
// #include <sys/stat.h>
// #include <fcntl.h>
// #include <stdbool.h> // For boolean data type (bool, true, false)
// #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;
// void *ptr1;
// void *ptr2;
// 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 Size)
// {
// size_t sz = __builtin_align_up(Size, _Alignof(max_align_t));
// MallocCounter -= sz;
// if (sz > MallocCounter) {
// printf("%d Threashold exceeded\n", sz);
// INITREGULARALLOC(1);
// }
// printf("%d \n", sz);
// printf("%d Malloc counter new\n", MallocCounter);
// void *ptrLink = &ptr[MallocCounter];
// // To investigate bounds set
// ptrLink = cheri_bounds_set(ptrLink, sz);
// // printf("%d Malloc counter assigned\n", MallocCounter);
// 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(int full) {
// size_t sz;
// // Hard-coded for 1GB huge page
// sz = 1073741824;
// int error, fd, pscnt, pn;
// size_t ps[MAXPAGESIZES];
// size_t size[3];
// // Point to initially to pointer 1
// if (full == 1) {
// ptr = ptr2;
// }
// else {
// ptr = ptr1;
// }
// 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_
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <cheriintrin.h>
#include <cheri/cheric.h>
#include <sys/stat.h>
#include <fcntl.h>
#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;
static size_t HEAP_SIZE = 102 4 * 1024 * 1024;
void *MALLOCCHERI(size_t sz) {
printf("printing malloc");
if (!heap) heap = heap_start = mmap(NULL, HEAP_SIZE,
PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON,-1,0);
sz = __builtin_align_up(sz, _Alignof(max_align_t));
if (heap + sz > heap_start + HEAP_SIZE) return NULL;
heap += sz;
return heap - sz;
}
// Quick malloc implementation with mmap
void* MALLOCCHERI(size_t sz)
{
sz = __builtin_align_up(sz, _Alignof(max_align_t));
void FREECHERI(void *ptr) { }
// 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;
void *realloc(void *ptr, size_t sz) {
void *new_ptr = malloc(sz);
if (ptr && new_ptr) memmove(new_ptr, ptr, sz);
return new_ptr;
}
// 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;
// Hard-coded for 1GB huge page
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_

View File

@@ -77,10 +77,10 @@ Command line options:
#include <math.h>
#include <time.h>
// #include "malloc.h"
#include "malloc.h"
// #define malloc MALLOCCHERI
// #define free FREECHERI
#define malloc MALLOCCHERI
#define free FREECHERI
string defv[] = { /* DEFAULT PARAMETER VALUES */
@@ -116,7 +116,7 @@ int argc;
string argv[];
{
// INITREGULARALLOC();
INITREGULARALLOC(0);
unsigned ProcessId = 0;
int c;

View File

@@ -33,7 +33,7 @@
#include <sys/errno.h>
#include <stdint.h>
#include <stdio.h>
// #include <unistd.h>
#include <unistd.h>
#include <stddef.h>
@@ -47,6 +47,7 @@
#include <sys/stat.h>
#include <fcntl.h>
#include <stdbool.h> // For boolean data type (bool, true, false)
#define MAXPAGESIZES 2
@@ -137,8 +138,10 @@ static char *heap_start;
static char *heap;
static size_t HEAP_SIZE = 1024 * 1024 * 1024;
void *ptrEspresso;
int MallocCounterEspresso;
void *ptr;
void *ptr1;
void *ptr2;
int MallocCounter;
size_t sizeUsed;
@@ -166,30 +169,42 @@ INITAlloc(void) {
// ptr = mmap(NULL, sz,
// PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON,-1,0);
ptrEspresso = mmap(NULL, sz,
ptr = mmap(NULL, sz,
PROT_READ|PROT_WRITE, MAP_SHARED,fd,0);
// Added error handling
if(ptrEspresso == MAP_FAILED)
if(ptr == MAP_FAILED)
{
perror("mmap");
exit(EXIT_FAILURE);
}
MallocCounterEspresso = (int)sz;
MallocCounter = (int)sz;
}
}
// Quick malloc implementation with mmap
void* MALLOCCHERI(size_t sz)
void* MALLOCCHERI(size_t Size)
{
sz = __builtin_align_up(sz, _Alignof(max_align_t));
size_t sz = __builtin_align_up(Size, _Alignof(max_align_t));
MallocCounter -= sz;
if (sz > MallocCounter) {
// printf("%d Threashold exceeded\n", sz);
INITREGULARALLOC(1);
}
// printf("%d \n", sz);
// printf("%d Malloc counter new\n", MallocCounter);
MallocCounterEspresso -= sz;
void *ptrLink = &ptrEspresso[MallocCounterEspresso];
ptrLink = cheri_setbounds(ptrLink, sz);
void *ptrLink = &ptr[MallocCounter];
// To investigate bounds set
ptrLink = cheri_bounds_set(ptrLink, sz);
// printf("%d Malloc counter assigned\n", MallocCounter);
return ptrLink;
@@ -229,7 +244,7 @@ pagesizes(size_t ps[MAXPAGESIZES])
return (pscnt);
}
INITREGULARALLOC(void) {
INITREGULARALLOC(int full) {
size_t sz;
// Hard-coded for 1GB huge page
sz = 1073741824;
@@ -240,6 +255,13 @@ INITREGULARALLOC(void) {
size_t size[3];
// Point to initially to pointer 1
if (full == 1) {
ptr = ptr2;
}
else {
ptr = ptr1;
}
pn = getpagesizes(size, 3);
printf("page size is [%d]", size[2]);
@@ -272,17 +294,17 @@ INITREGULARALLOC(void) {
// atf_tc_skip("failed to allocate %zu-byte superpage", sz);
// ATF_REQUIRE_MSG(error == 0, "ftruncate failed; errno=%d", errno);
ptrEspresso = mmap(NULL, sz,
ptr = mmap(NULL, sz,
PROT_READ|PROT_WRITE, MAP_SHARED,fd,0);
// Added error handling
if(ptrEspresso == MAP_FAILED)
if(ptr == MAP_FAILED)
{
perror("mmap");
exit(EXIT_FAILURE);
}
MallocCounterEspresso = (int)sz;
MallocCounter = (int)sz;
}
// Standard Alloc
// void* MALLOCREGULAR(size_t sz) {
@@ -295,3 +317,5 @@ INITREGULARALLOC(void) {
// }
#endif // STDDEFINES_H_

View File

@@ -184,7 +184,7 @@ int main(argc, argv)
{
INITREGULARALLOC(0);
// INITREGULARALLOC(0);
unsigned m = 0, k = 0;
unsigned maxCount = 1<<30, count, maxk = 0;

View File

@@ -1,316 +1,346 @@
/* 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.
*/
// /* 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_
// #ifndef STDDEFINES_H_
// #define STDDEFINES_H_
#include <assert.h>
#include <stdlib.h>
#include <sys/time.h>
#include <sys/errno.h>
#include <stdint.h>
#include <stdio.h>
#include <unistd.h>
// #include <assert.h>
// #include <stdlib.h>
// #include <sys/time.h>
// #include <sys/errno.h>
// #include <stdint.h>
// #include <stdio.h>
// #include <unistd.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/types.h>
// #include <stddef.h>
// #include <stdlib.h>
// #include <string.h>
// #include <sys/mman.h>
// #include <sys/types.h>
#include <cheriintrin.h>
#include <cheri/cheric.h>
// #include <cheriintrin.h>
// #include <cheri/cheric.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdbool.h> // For boolean data type (bool, true, false)
// #include <sys/stat.h>
// #include <fcntl.h>
// #include <stdbool.h> // For boolean data type (bool, true, false)
#define MAXPAGESIZES 2
// #define MAXPAGESIZES 2
//#define TIMING
// //#define TIMING
/* Debug printf */
#define dprintf(...) fprintf(stdout, __VA_ARGS__)
// /* 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); \
}
// /* 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 *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 *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 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;
}
// 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; \
}
// #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)
// static inline unsigned int time_diff (
// struct timeval *end, struct timeval *begin)
// {
// #ifdef TIMING
// gettimeofday (t, NULL);
// 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
// }
// Expirement work
// // static inline void get_time (struct timeval *t)
// // {
// // #ifdef TIMING
// // gettimeofday (t, NULL);
// // #endif
// // }
#define FILENAME "/dev/contigmem"
// // Expirement work
static char *heap_start;
static char *heap;
static size_t HEAP_SIZE = 1024 * 1024 * 1024;
// #define FILENAME "/dev/contigmem"
void *ptr;
void *ptr1;
void *ptr2;
int MallocCounter;
// static char *heap_start;
// static char *heap;
// static size_t HEAP_SIZE = 1024 * 1024 * 1024;
size_t sizeUsed;
// void *ptr;
// void *ptr1;
// void *ptr2;
// int MallocCounter;
INITAlloc(void) {
// size_t sizeUsed;
size_t sz;
// Pre Allocate 600 MB
sz = 100000000;
// INITAlloc(void) {
int fd = open(FILENAME, O_RDWR, 0600);
// size_t sz;
// // Pre Allocate 600 MB
// sz = 100000000;
if (fd < 0) {
perror("open");
exit(EXIT_FAILURE);
}
// int fd = open(FILENAME, O_RDWR, 0600);
off_t offset = 0; // offset to seek to.
// if (fd < 0) {
// perror("open");
// exit(EXIT_FAILURE);
// }
if (ftruncate(fd, sz) < 0) {
perror("ftruncate");
close(fd);
exit(EXIT_FAILURE);
}
// off_t offset = 0; // offset to seek to.
// ptr = mmap(NULL, sz,
// PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON,-1,0);
// if (ftruncate(fd, sz) < 0) {
// perror("ftruncate");
// close(fd);
// exit(EXIT_FAILURE);
// }
ptr = mmap(NULL, sz,
PROT_READ|PROT_WRITE, MAP_SHARED,fd,0);
// // ptr = mmap(NULL, sz,
// // PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON,-1,0);
// Added error handling
if(ptr == MAP_FAILED)
{
perror("mmap");
exit(EXIT_FAILURE);
}
// ptr = mmap(NULL, sz,
// PROT_READ|PROT_WRITE, MAP_SHARED,fd,0);
MallocCounter = (int)sz;
// // 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));
// }
if (sz > MallocCounter) {
printf("%d Threashold exceeded\n", sz);
INITREGULARALLOC(1);
}
// // Quick malloc implementation with mmap
// void* MALLOCCHERI(size_t Size)
// {
// size_t sz = __builtin_align_up(Size, _Alignof(max_align_t));
MallocCounter -= sz;
// MallocCounter -= sz;
// printf("%d \n", sz);
printf("%d Malloc counter new\n", MallocCounter);
// if (sz > MallocCounter) {
// printf("%d Threashold exceeded\n", sz);
// INITREGULARALLOC(1);
// }
void *ptrLink = &ptr[MallocCounter];
ptrLink = cheri_bounds_set(ptrLink, sz);
return ptrLink;
// // printf("%d \n", sz);
// printf("%d Malloc counter new\n", MallocCounter);
// void *ptrLink = &ptr[MallocCounter];
// // To investigate bounds set
// ptrLink = cheri_bounds_set(ptrLink, sz);
// printf("%d Malloc counter assigned\n", MallocCounter);
// 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(int full) {
// size_t sz;
// // Hard-coded for 1GB huge page
// sz = 1073741824;
// int error, fd, pscnt, pn;
// size_t ps[MAXPAGESIZES];
// size_t size[3];
// // Point to initially to pointer 1
// if (full == 1) {
// ptr = ptr2;
// }
// else {
// ptr = ptr1;
// }
// 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_
// #include <stddef.h>
// #include <stdlib.h>
// #include <string.h>
// #include <sys/mman.h>
// static char *heap_start;
// static char *heap;
// static size_t HEAP_SIZE = 1024 * 1024 * 1024;
// void * MALLOCCHERI(size_t sz) {
// if (!heap) heap = heap_start = mmap(NULL, HEAP_SIZE,
// PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON,-1,0);
// sz = __builtin_align_up(sz, _Alignof(max_align_t));
// 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(int full) {
size_t sz;
// Hard-coded for 1GB huge page
sz = 1073741824;
int error, fd, pscnt, pn;
size_t ps[MAXPAGESIZES];
size_t size[3];
// Point to initially to pointer 1
if (full == 1) {
ptr = ptr2;
}
else {
ptr = ptr1;
}
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 FREECHERI(void *ptr) { }
// void* CLEARALLOC(void) {
// /
// void *realloc(void *ptr, size_t sz) {
// void *new_ptr = malloc(sz);
// if (ptr && new_ptr) memmove(new_ptr, ptr, sz);
// return new_ptr;
// }
#endif // STDDEFINES_H_

View File

@@ -338,15 +338,18 @@ uvec pfactorbase(n, k, m, aborts)
#ifdef BWGC
res = (uvec) gc_malloc(count * sizeof (unsigned));
#else
printf("reaches here");
printf("reaches here new");
// printf("reaches here\n");
res = (uvec) malloc(count * sizeof (unsigned));
printf("malloc allocated");
#endif
// printf("malloc allocated\n");
#endif
// printf("called after end if \n");
if (res == (uvec) 0) goto doneMk;
// printf("setting res to pm \n");
pm = res;
// printf("setting res is set \n");
*pm++ = (unsigned) *primePtr++; /* two is first element */
// printf("prime number increment \n");
count = 1;
if (count != *m) do {
if (picmp(plegendre(nk, utop((unsigned) *primePtr)), 1) <= 0) { /* 0,1 */
@@ -359,7 +362,10 @@ uvec pfactorbase(n, k, m, aborts)
} while (*primePtr != 1);
*m = count;
// printf("end of function\n");
doneMk:
// printf("calling destroy \n");
pdestroy(nk);
pdestroy(n);
return res;

View File

@@ -23,7 +23,7 @@ void gmalloc_exit(void);
static int mainx(int argc, char* argv[]);
int main(int argc, char* argv[]) {
INITREGULARALLOC();
INITREGULARALLOC(0);
int i;
extern int optind;
for(i = 0; i < 20; i++) { // benchmark N iterations

View File

@@ -47,6 +47,7 @@
#include <sys/stat.h>
#include <fcntl.h>
#include <stdbool.h> // For boolean data type (bool, true, false)
#define MAXPAGESIZES 2
@@ -92,35 +93,35 @@
// 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; \
// }
#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;
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;
result = end->tv_sec - begin->tv_sec;
result *= 1000000; /* usec */
result += end->tv_usec - begin->tv_usec;
// return result;
// #else
// return 0;
// #endif
// }
return result;
#else
return 0;
#endif
}
// static inline void get_time (struct timeval *t)
// {
@@ -137,8 +138,10 @@ static char *heap_start;
static char *heap;
static size_t HEAP_SIZE = 1024 * 1024 * 1024;
void *ptrEspresso;
int MallocCounterEspresso;
void *ptr;
void *ptr1;
void *ptr2;
int MallocCounter;
size_t sizeUsed;
@@ -166,40 +169,45 @@ INITAlloc(void) {
// ptr = mmap(NULL, sz,
// PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON,-1,0);
ptrEspresso = mmap(NULL, sz,
ptr = mmap(NULL, sz,
PROT_READ|PROT_WRITE, MAP_SHARED,fd,0);
// Added error handling
if(ptrEspresso == MAP_FAILED)
if(ptr == MAP_FAILED)
{
perror("mmap");
exit(EXIT_FAILURE);
}
MallocCounterEspresso = (int)sz;
MallocCounter = (int)sz;
}
int sizeCounter = 0;
}
// Quick malloc implementation with mmap
void* MALLOCCHERI(size_t sz)
void* MALLOCCHERI(size_t Size)
{
sz = __builtin_align_up(sz, _Alignof(max_align_t));
size_t sz = __builtin_align_up(Size, _Alignof(max_align_t));
// // printf("%d \n", sz);
MallocCounter -= sz;
sizeCounter += sz;
printf("%d Malloc counter\n", sizeCounter);
if (sz > MallocCounter) {
printf("%d Threashold exceeded\n", sz);
INITREGULARALLOC(1);
}
MallocCounterEspresso -= sz;
void *ptrLink = &ptrEspresso[MallocCounterEspresso];
ptrLink = cheri_setbounds(ptrLink, sz);
printf("%d \n", sz);
printf("%d Malloc counter new\n", MallocCounter);
void *ptrLink = &ptr[MallocCounter];
// To investigate bounds set
ptrLink = cheri_bounds_set(ptrLink, sz);
// printf("%d Malloc counter assigned\n", MallocCounter);
return ptrLink;
// return malloc(sz);
// if (heap + sz > heap_start + HEAP_SIZE) return NULL;
// heap += sz;
// return heap - sz;
@@ -217,9 +225,7 @@ void FREECHERI(void *ptr) {
// printf("free len %d \n", len);
munmap(ptr, len);
free(ptr);
}
}
static int
pagesizes(size_t ps[MAXPAGESIZES])
@@ -238,7 +244,7 @@ pagesizes(size_t ps[MAXPAGESIZES])
return (pscnt);
}
INITREGULARALLOC(void) {
INITREGULARALLOC(int full) {
size_t sz;
// Hard-coded for 1GB huge page
sz = 1073741824;
@@ -249,6 +255,13 @@ INITREGULARALLOC(void) {
size_t size[3];
// Point to initially to pointer 1
if (full == 1) {
ptr = ptr2;
}
else {
ptr = ptr1;
}
pn = getpagesizes(size, 3);
printf("page size is [%d]", size[2]);
@@ -281,17 +294,17 @@ INITREGULARALLOC(void) {
// atf_tc_skip("failed to allocate %zu-byte superpage", sz);
// ATF_REQUIRE_MSG(error == 0, "ftruncate failed; errno=%d", errno);
ptrEspresso = mmap(NULL, sz,
ptr = mmap(NULL, sz,
PROT_READ|PROT_WRITE, MAP_SHARED,fd,0);
// Added error handling
if(ptrEspresso == MAP_FAILED)
if(ptr == MAP_FAILED)
{
perror("mmap");
exit(EXIT_FAILURE);
}
MallocCounterEspresso = (int)sz;
MallocCounter = (int)sz;
}
// Standard Alloc
// void* MALLOCREGULAR(size_t sz) {
@@ -304,3 +317,5 @@ INITREGULARALLOC(void) {
// }
#endif // STDDEFINES_H_

View File

@@ -0,0 +1,31 @@
* Evaluation section planning
This will consist of a paragraph of the following structure:
- 2 senteces on the expirement setup.
- 2 sentences of ther Micro benchmarks.
- 2 sentences on the Macro benchmarks.
- Quick overview of the upcoming sections
** Expirement setup
- Mentions about the CHERI board used.
- specs of the board
- mentions about the compiled flag called benchmark ABI.(https://ctsrd-cheri.github.io/morello-early-performance-results/performance-methodology/abis-code-generation-and-compilation.html)
- mentions how the various benchmark are compared and breifly
mentions about the ARM performance counters.
** Performance counters used
- Mentions about the performance counters used.
In a Tabular strucuture.
** Lists of the type of benchmarks ran with the descriptions on the side
This is more in a bulletin point manner.
** Graphs listed
- Talks about each of the benchmark patterns indenpendently (Bulletin points elaborated).
- Builds up on those with multiple runs.
** Usability:
Talk about the ease of running the new allocator.
- Limitaion why certain benchmarks did not work.
- The eager Huge page design while designed for fragmentation can still incur fragmentation at
a user level.
- How was the memory allocator swapped.

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

View File

@@ -0,0 +1,31 @@
* Evaluation section planning
This will consist of a paragraph of the following structure:
- 2 senteces on the expirement setup.
- 2 sentences of ther Micro benchmarks.
- 2 sentences on the Macro benchmarks.
- Quick overview of the upcoming sections
** Expirement setup
- Mentions about the CHERI board used.
- specs of the board
- mentions about the compiled flag called benchmark ABI.
- mentions how the various bechmark are compared and breifly
mentions about the ARM performance counters.
** Performance counters used
- Mentions about the performance counters used.
In a Tabular strucuture.
** Lists of the type of benchmarks ran with the descriptions on the side
This is more in a bulletin point manner.
** Graphs listed
- Talks about each of the benchmark patterns indenpendently (Bulletin points elaborated).
- Builds up on those with multiple runs.
** Usability:
Talk about the ease of running the new allocator.
- Limitaion why certain benchmarks did not work.
- The eager Huge page design while designed for fragmentation can still incur fragmentation at
a user level.
- How was the memory allocator swapped.

View File

@@ -0,0 +1,6 @@
@online{cheribsd,
title = {Benchmark {ABI} - {CheriBSD} 23.11 new features tutorial},
url = {https://www.cheribsd.org/tutorial/23.11/benchmark/index.html},
urldate = {2024-06-07},
file = {Benchmark ABI - CheriBSD 23.11 new features tutorial:/Users/akilan/Zotero/storage/9BDKUW28/index.html:text/html},
}

View File

@@ -0,0 +1,6 @@
@online{cheribsd,
title = {Benchmark {ABI} - {CheriBSD} 23.11 new features tutorial},
url = {https://www.cheribsd.org/tutorial/23.11/benchmark/index.html},
urldate = {2024-06-07},
file = {Benchmark ABI - CheriBSD 23.11 new features tutorial:/Users/akilan/Zotero/storage/9BDKUW28/index.html:text/html},
}

View File

@@ -0,0 +1,207 @@
* Evaluation
#+bibliography: evaluation.bib
#+BEGIN_COMMENT
We tested the FAT Pointer based range addresses
against Jemalloc the default memory allocator
for CHERIBSD. We evaluate the general improvement
in performance such as wall clock runtime by
reducing the TLB misses by designing a CHERI
based huge page aware allocator. There are
2 classes of benchmarks proposed for
evaluating the proposed allocator against the
system allocator. The 2 classes are mirco and macro
benchmarks. The micro benchmark refers to the specific
set of smaller C programs designed to test certain
specific allocator patterns. The macro benchmark
refers to larger set of C programs to evaluate real
world programs. The sections listed below diveldge
into the following:
- Expirement setup which talks about the software stack
used for evaluating the benchmark.
- Expanding on the classes of C programs executed
and describing the characterics of each of the
c programs.
- Listing the results and describing the behavoir of the
evaluated results.
- Describing the usability of the proposed allocator based
on the evaluated results and limitations identified.
#+END_COMMENT
We conducted tests of the FAT Pointer-based range addresses against Jemalloc,
the default memory allocator for CHERIBSD[cite:@cheribsd], to assess the performance improvements
enabled by a CHERI-based huge page-aware allocator. Specifically, we evaluated
the reduction in TLB misses and its impact on overall
performance metrics, such as wall clock runtime.
To comprehensively analyze the proposed allocator, we categorized benchmarks into
two classes which are micro and macro benchmarks. Micro benchmarks comprise smaller
C programs designed to target specific allocator patterns, enabling us to evaluate
detailed aspects of the allocator's behavior. Macro benchmarks, on the other hand,
encompass larger, real-world C programs, allowing us to assess the allocator's
performance in more practical, real-world scenarios.
The experiment setup details the software stack used for evaluation. It includes
the specific configurations, compiler options, and system environment tailored
to benchmark the proposed allocator. This ensures consistency and repeatability
in our results, providing a solid foundation for meaningful comparisons.
We further elaborated on the two classes of benchmarks executed. Micro benchmarks
focused on particular allocation and deallocation patterns, such as sequential and
random memory accesses, to stress-test the allocator under controlled conditions.
Macro benchmarks involved real-world applications, offering insights into how
the allocator performs with complex memory allocation demands, large datasets,
and varying execution contexts.
The results section presents the outcomes of our benchmarks, highlighting key metrics
such as TLB miss rates, memory usage, and runtime performance. We observed that the
proposed allocator demonstrated significant improvements in reducing TLB misses,
leading to noticeable enhancements in runtime efficiency for both micro and macro
benchmarks. The behavior of specific allocation patterns and their impact on memory
performance is detailed, providing a nuanced understanding of the allocator's effectiveness.
Based on the evaluated results, the usability of the proposed allocator shows promise
for applications requiring optimized memory management and reduced overhead from TLB misses.
However, limitations were also identified, such as scenarios where the allocator's performance
gains were marginal or where it introduced additional complexity in memory management. These
limitations provide a roadmap for future optimizations and refinements of the allocator design.
** Expirement setup
#+BEGIN_COMMENT
The CHERI morello board was used to evaluate tehe proposed memory allocator.
Morello implements the ARM A76 with enhanced server class memory. The speciafication
includes a quad core ARM CPU with capabilties. The L1 and L2 cache was modified to
proliferate the capability bit. When compiling the C program for benchmarking
the Benchmark ABI was used as recommended by the CHERI community as a compliation
mode with the Clang compilier.
The benchmark ABI was designed because the Morello
branch-predictor was not expanded to predict bounds. As a result, a capability-based
jump will stall later PCC-dependent instructions until bounds are established.
This is particularly problematic across dynamically linked calls
(and returns) between libraries, which will change bounds to those
covering the called (or returned-to) library.
Each C program is executed with 2 memory allocators. The first one being
the modified C allocator which is imported as a header file. This is because
the benchmark ABI shared object file has an unexpected behavoir of not overwriting
the C program on run time with the expected malloc functions to be overwritten.
The 2nd one being the standard OS memory allocator which in the case of CHERIBSD
is Jemalloc. The measurements are done using the ARM performance counters as mentioned
in the following section.
#+END_COMMENT
The CHERI Morello board was used to evaluate the proposed memory allocator.
Morello implements the ARM A76 with enhanced server-class memory, featuring a
quad-core ARM CPU with capability extensions. The L1 and L2 caches were modified
to proliferate the capability bit, ensuring compatibility with CHERI's capability-based
memory model. When compiling the C programs for benchmarking, the Benchmark ABI was
used as recommended by the CHERI community. This compilation mode was enabled using
the Clang compiler.
The Benchmark ABI was specifically designed because the Morello branch predictor
was not expanded to predict bounds. Consequently, a capability-based jump introduces
stalls in later PCC-dependent instructions until bounds are established. This issue
is particularly significant during dynamically linked calls and returns between
libraries, where bounds are changed to cover the called or returned-to library.
Such stalls can negatively affect performance, making the Benchmark ABI an essential
consideration for this evaluation.
Each C program was executed using two different memory allocators. The first was
the modified C allocator, imported as a header file. This approach was necessary
because the Benchmark ABI shared object file exhibited unexpected behavior,
failing to overwrite the C program at runtime with the intended malloc functions.
The second allocator was the standard OS memory allocator, which, in the case of
CHERIBSD, is Jemalloc.
Performance measurements were carried out using ARM performance counters to
ensure accurate evaluation. These counters provided detailed metrics, allowing
us to compare the performance of the two allocators and assess the impact of
the proposed changes.
*** Performance counters used
+--------------------------------------------------+--------------------------------------------+
| Performance counter | Description |
+--------------------------------------------------+--------------------------------------------+
| Wall clock | The actual time taken from the start of a |
| | computer program to the end. |
| | |
| (p/l1d_tlb_rd) L1 data TLB reads | Level 1 data TLB access, read |
| | |
| (p/l2d_tlb_rd) L2 data TLB reads | Level 2 data TLB access, read |
| | |
| (p/l1d_tlb_refill) L1 data TLB refills | Level 1 data TLB refill. |
| | The Level 1 data TLB refill |
| | counter tracks each access to |
| | the L1D_TLB that results |
| | in a refill of the Level 1 data |
| | or unified TLB. This includes any |
| | access that requires a memory lookup |
| | due to a translation table walk |
| | or accessing another level of TLB cache. |
| | |
| (p/cpu_cycles) CPU cycles | The CPU CYCLES counter increases with |
| | every clock cycle. However, it can be |
| | affected by changes in clock frequency, |
| | such as when WFI (Wait for Interrupt) |
| | or WFE (Wait for Event) |
| | instructions pause the clock. |
| | |
| (p/dtlb_walk) Data TLB walks | Data TLB access with at least |
| | one translation table walk. |
| | |
| (p/ll_cache_miss_rd) Last level cache miss reads | Last level cache miss, read |
| | (This refers to every miss in the |
| | Last level cache that occurs |
| | during a memory read operation.) |
+--------------------------------------------------+--------------------------------------------+
*** Benchmarks
The benchmarks are classified into 2 classes:
**** Micro benchmark
- GLIBC: The Glibc benchmark evaluates the performance of
malloc and free functions in single-threaded, multi-threaded,
and emulated multi-threading scenarios using various block sizes and
allocation patterns. It simulates real-world memory usage by partially
deallocating blocks in FIFO order and fully deallocating them in LIFO order.
Results are gathered across configurations to analyze performance variations.
- MemAccess: This benchmark by Alex Bordei evaluates the performance impact of
memory access patterns by constructing and traversing a doubly
linked list with varying working set sizes. It supports sequential or
randomized structures, optional node operations, and multithreaded
traversal using pthreads. The program dynamically allocates memory and systematically
doubles the working set size to analyze memory hierarchy behavior.
**** Macro runs
- Kmeans: Kmeans implements a parallelized K-means clustering algorithm that
assigns data points to clusters based on proximity to centroids,
iteratively updating them until convergence. The computation is
distributed across threads using the pthread library, dynamically
assigning tasks to optimize performance. Parameters like data size
and clusters are configurable, and the program ensures efficient
memory management and synchronization.
- Richards: Richards is a task scheduling benchmark that simulates a
multitasking environment with tasks of varying types and priorities,
communicating through queued packets. The schedule function manages
task execution based on state and priority, tracking processed packets
and held tasks for performance evaluation. Configurable iterations and
timing help measure system performance and ensure correctness.
** Results
#+ATTR_HTML: :align right
#+ATTR_ORG: :align center
[[./diagrams/allbenchmarks.png]]
#+ATTR_HTML: :align right
#+ATTR_ORG: :align center
[[./diagrams/kmeans.png]]
#+ATTR_HTML: :align right
#+ATTR_ORG: :align center
[[./diagrams/glibc.png]]
** Usability

View File

@@ -0,0 +1,222 @@
* Evaluation
#+bibliography: evaluation.bib
#+BEGIN_COMMENT
We tested the FAT Pointer based range addresses
against Jemalloc the default memory allocator
for CHERIBSD. We evaluate the general improvement
in performance such as wall clock runtime by
reducing the TLB misses by designing a CHERI
based huge page aware allocator. There are
2 classes of benchmarks proposed for
evaluating the proposed allocator against the
system allocator. The 2 classes are mirco and macro
benchmarks. The micro benchmark refers to the specific
set of smaller C programs designed to test certain
specific allocator patterns. The macro benchmark
refers to larger set of C programs to evaluate real
world programs. The sections listed below diveldge
into the following:
- Expirement setup which talks about the software stack
used for evaluating the benchmark.
- Expanding on the classes of C programs executed
and describing the characterics of each of the
c programs.
- Listing the results and describing the behavoir of the
evaluated results.
- Describing the usability of the proposed allocator based
on the evaluated results and limitations identified.
#+END_COMMENT
We conducted tests of the FAT Pointer-based range addresses against Jemalloc,
the default memory allocator for CHERIBSD[cite:@cheribsd], to assess the performance improvements
enabled by a CHERI-based huge page-aware allocator. Specifically, we evaluated
the reduction in TLB misses and its impact on overall
performance metrics, such as wall clock runtime.
To comprehensively analyze the proposed allocator, we categorized benchmarks into
two classes which are micro and macro benchmarks. Micro benchmarks comprise smaller
C programs designed to target specific allocator patterns, enabling us to evaluate
detailed aspects of the allocator's behavior. Macro benchmarks, on the other hand,
encompass larger, real-world C programs, allowing us to assess the allocator's
performance in more practical, real-world scenarios.
The experiment setup details the software stack used for evaluation. It includes
the specific configurations, compiler options, and system environment tailored
to benchmark the proposed allocator. This ensures consistency and repeatability
in our results, providing a solid foundation for meaningful comparisons.
We further elaborated on the two classes of benchmarks executed. Micro benchmarks
focused on particular allocation and deallocation patterns, such as sequential and
random memory accesses, to stress-test the allocator under controlled conditions.
Macro benchmarks involved real-world applications, offering insights into how
the allocator performs with complex memory allocation demands, large datasets,
and varying execution contexts.
The results section presents the outcomes of our benchmarks, highlighting key metrics
such as TLB miss rates, memory usage, and runtime performance. We observed that the
proposed allocator demonstrated significant improvements in reducing TLB misses,
leading to noticeable enhancements in runtime efficiency for both micro and macro
benchmarks. The behavior of specific allocation patterns and their impact on memory
performance is detailed, providing a nuanced understanding of the allocator's effectiveness.
Based on the evaluated results, the usability of the proposed allocator shows promise
for applications requiring optimized memory management and reduced overhead from TLB misses.
However, limitations were also identified, such as scenarios where the allocator's performance
gains were marginal or where it introduced additional complexity in memory management. These
limitations provide a roadmap for future optimizations and refinements of the allocator design.
** Expirement setup
#+BEGIN_COMMENT
The CHERI morello board was used to evaluate tehe proposed memory allocator.
Morello implements the ARM A76 with enhanced server class memory. The speciafication
includes a quad core ARM CPU with capabilties. The L1 and L2 cache was modified to
proliferate the capability bit. When compiling the C program for benchmarking
the Benchmark ABI was used as recommended by the CHERI community as a compliation
mode with the Clang compilier.
The benchmark ABI was designed because the Morello
branch-predictor was not expanded to predict bounds. As a result, a capability-based
jump will stall later PCC-dependent instructions until bounds are established.
This is particularly problematic across dynamically linked calls
(and returns) between libraries, which will change bounds to those
covering the called (or returned-to) library.
Each C program is executed with 2 memory allocators. The first one being
the modified C allocator which is imported as a header file. This is because
the benchmark ABI shared object file has an unexpected behavoir of not overwriting
the C program on run time with the expected malloc functions to be overwritten.
The 2nd one being the standard OS memory allocator which in the case of CHERIBSD
is Jemalloc. The measurements are done using the ARM performance counters as mentioned
in the following section.
#+END_COMMENT
The CHERI Morello board was used to evaluate the proposed memory allocator.
Morello implements the ARM A76 with enhanced server-class memory, featuring a
quad-core ARM CPU with capability extensions. The L1 and L2 caches were modified
to proliferate the capability bit, ensuring compatibility with CHERI's capability-based
memory model. When compiling the C programs for benchmarking, the Benchmark ABI was
used as recommended by the CHERI community. This compilation mode was enabled using
the Clang compiler.
The Benchmark ABI was specifically designed because the Morello branch predictor
was not expanded to predict bounds. Consequently, a capability-based jump introduces
stalls in later PCC-dependent instructions until bounds are established. This issue
is particularly significant during dynamically linked calls and returns between
libraries, where bounds are changed to cover the called or returned-to library.
Such stalls can negatively affect performance, making the Benchmark ABI an essential
consideration for this evaluation.
Each C program was executed using two different memory allocators. The first was
the modified C allocator, imported as a header file. This approach was necessary
because the Benchmark ABI shared object file exhibited unexpected behavior,
failing to overwrite the C program at runtime with the intended malloc functions.
The second allocator was the standard OS memory allocator, which, in the case of
CHERIBSD, is Jemalloc.
Performance measurements were carried out using ARM performance counters to
ensure accurate evaluation. These counters provided detailed metrics, allowing
us to compare the performance of the two allocators and assess the impact of
the proposed changes.
*** Performance counters used
+--------------------------------------------------+--------------------------------------------+
| Performance counter | Description |
+--------------------------------------------------+--------------------------------------------+
| Wall clock | The actual time taken from the start of a |
| | computer program to the end. |
| | |
| (p/l1d_tlb_rd) L1 data TLB reads | Level 1 data TLB access, read |
| | |
| (p/l2d_tlb_rd) L2 data TLB reads | Level 2 data TLB access, read |
| | |
| (p/l1d_tlb_refill) L1 data TLB refills | Level 1 data TLB refill. |
| | The Level 1 data TLB refill |
| | counter tracks each access to |
| | the L1D_TLB that results |
| | in a refill of the Level 1 data |
| | or unified TLB. This includes any |
| | access that requires a memory lookup |
| | due to a translation table walk |
| | or accessing another level of TLB cache. |
| | |
| (p/cpu_cycles) CPU cycles | The CPU CYCLES counter increases with |
| | every clock cycle. However, it can be |
| | affected by changes in clock frequency, |
| | such as when WFI (Wait for Interrupt) |
| | or WFE (Wait for Event) |
| | instructions pause the clock. |
| | |
| (p/dtlb_walk) Data TLB walks | Data TLB access with at least |
| | one translation table walk. |
| | |
| (p/ll_cache_miss_rd) Last level cache miss reads | Last level cache miss, read |
| | (This refers to every miss in the |
| | Last level cache that occurs |
| | during a memory read operation.) |
+--------------------------------------------------+--------------------------------------------+
*** Benchmarks
#+BEGIN_COMMENT
**** Real world
Kmeans
Barnes
Richards
Todo
Espresso
Cfrac
**** Stress test
GLibC
MemAccess
Loadmem
Todo
xmalloc-test
#+END_COMMENT
The benchmarks are classified into 2 classes:
**** Micro benchmark
- GLIBC: The Glibc benchmark evaluates the performance of
malloc and free functions in single-threaded, multi-threaded,
and emulated multi-threading scenarios using various block sizes and
allocation patterns. It simulates real-world memory usage by partially
deallocating blocks in FIFO order and fully deallocating them in LIFO order.
Results are gathered across configurations to analyze performance variations.
- MemAccess: This benchmark by Alex Bordei evaluates the performance impact of
memory access patterns by constructing and traversing a doubly
linked list with varying working set sizes. It supports sequential or
randomized structures, optional node operations, and multithreaded
traversal using pthreads. The program dynamically allocates memory and systematically
doubles the working set size to analyze memory hierarchy behavior.
**** Macro runs
- Kmeans: Kmeans implements a parallelized K-means clustering algorithm that
assigns data points to clusters based on proximity to centroids,
iteratively updating them until convergence. The computation is
distributed across threads using the pthread library, dynamically
assigning tasks to optimize performance. Parameters like data size
and clusters are configurable, and the program ensures efficient
memory management and synchronization.
- Richards: Richards is a task scheduling benchmark that simulates a
multitasking environment with tasks of varying types and priorities,
communicating through queued packets. The schedule function manages
task execution based on state and priority, tracking processed packets
and held tasks for performance evaluation. Configurable iterations and
timing help measure system performance and ensure correctness.
** Results
#+ATTR_HTML: :align right
#+ATTR_ORG: :align center
[[./diagrams/allbenchmarks.png]]
#+ATTR_HTML: :align right
#+ATTR_ORG: :align center
[[./diagrams/kmeans.png]]
#+ATTR_HTML: :align right
#+ATTR_ORG: :align center
[[./diagrams/glibc.png]]
** Usability

Binary file not shown.

View File

@@ -0,0 +1,201 @@
% Created 2025-01-09 Thu 22:53
% Intended LaTeX compiler: pdflatex
\documentclass[11pt]{article}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{graphicx}
\usepackage{longtable}
\usepackage{wrapfig}
\usepackage{rotating}
\usepackage[normalem]{ulem}
\usepackage{amsmath}
\usepackage{amssymb}
\usepackage{capt-of}
\usepackage{hyperref}
\author{Akilan}
\date{\today}
\title{}
\hypersetup{
pdfauthor={Akilan},
pdftitle={},
pdfkeywords={},
pdfsubject={},
pdfcreator={Emacs 29.1 (Org mode 9.6.6)},
pdflang={English}}
\begin{document}
\tableofcontents
\section{Evaluation}
\label{sec:org02aba25}
We conducted tests of the FAT Pointer-based range addresses against Jemalloc,
the default memory allocator for CHERIBSD(, ), to assess the performance improvements
enabled by a CHERI-based huge page-aware allocator. Specifically, we evaluated
the reduction in TLB misses and its impact on overall
performance metrics, such as wall clock runtime.
To comprehensively analyze the proposed allocator, we categorized benchmarks into
two classes which are micro and macro benchmarks. Micro benchmarks comprise smaller
C programs designed to target specific allocator patterns, enabling us to evaluate
detailed aspects of the allocator's behavior. Macro benchmarks, on the other hand,
encompass larger, real-world C programs, allowing us to assess the allocator's
performance in more practical, real-world scenarios.
The experiment setup details the software stack used for evaluation. It includes
the specific configurations, compiler options, and system environment tailored
to benchmark the proposed allocator. This ensures consistency and repeatability
in our results, providing a solid foundation for meaningful comparisons.
We further elaborated on the two classes of benchmarks executed. Micro benchmarks
focused on particular allocation and deallocation patterns, such as sequential and
random memory accesses, to stress-test the allocator under controlled conditions.
Macro benchmarks involved real-world applications, offering insights into how
the allocator performs with complex memory allocation demands, large datasets,
and varying execution contexts.
The results section presents the outcomes of our benchmarks, highlighting key metrics
such as TLB miss rates, memory usage, and runtime performance. We observed that the
proposed allocator demonstrated significant improvements in reducing TLB misses,
leading to noticeable enhancements in runtime efficiency for both micro and macro
benchmarks. The behavior of specific allocation patterns and their impact on memory
performance is detailed, providing a nuanced understanding of the allocator's effectiveness.
Based on the evaluated results, the usability of the proposed allocator shows promise
for applications requiring optimized memory management and reduced overhead from TLB misses.
However, limitations were also identified, such as scenarios where the allocator's performance
gains were marginal or where it introduced additional complexity in memory management. These
limitations provide a roadmap for future optimizations and refinements of the allocator design.
\subsection{Expirement setup}
\label{sec:org9bf5b27}
The CHERI Morello board was used to evaluate the proposed memory allocator.
Morello implements the ARM A76 with enhanced server-class memory, featuring a
quad-core ARM CPU with capability extensions. The L1 and L2 caches were modified
to proliferate the capability bit, ensuring compatibility with CHERI's capability-based
memory model. When compiling the C programs for benchmarking, the Benchmark ABI was
used as recommended by the CHERI community. This compilation mode was enabled using
the Clang compiler.
The Benchmark ABI was specifically designed because the Morello branch predictor
was not expanded to predict bounds. Consequently, a capability-based jump introduces
stalls in later PCC-dependent instructions until bounds are established. This issue
is particularly significant during dynamically linked calls and returns between
libraries, where bounds are changed to cover the called or returned-to library.
Such stalls can negatively affect performance, making the Benchmark ABI an essential
consideration for this evaluation.
Each C program was executed using two different memory allocators. The first was
the modified C allocator, imported as a header file. This approach was necessary
because the Benchmark ABI shared object file exhibited unexpected behavior,
failing to overwrite the C program at runtime with the intended malloc functions.
The second allocator was the standard OS memory allocator, which, in the case of
CHERIBSD, is Jemalloc.
Performance measurements were carried out using ARM performance counters to
ensure accurate evaluation. These counters provided detailed metrics, allowing
us to compare the performance of the two allocators and assess the impact of
the proposed changes.
\subsubsection{Performance counters used}
\label{sec:org294979c}
\begin{center}
\begin{tabular}{|l|l|}
\hline
Performance counter & Description \\
\hline
Wall clock & The actual time taken from the start of a \\
& computer program to the end. \\
& \\
(p/l1d\_tlb\_rd) L1 data TLB reads & Level 1 data TLB access, read \\
& \\
(p/l2d\_tlb\_rd) L2 data TLB reads & Level 2 data TLB access, read \\
& \\
(p/l1d\_tlb\_refill) L1 data TLB refills & Level 1 data TLB refill. \\
& The Level 1 data TLB refill \\
& counter tracks each access to \\
& the L1D\_TLB that results \\
& in a refill of the Level 1 data \\
& or unified TLB. This includes any \\
& access that requires a memory lookup \\
& due to a translation table walk \\
& or accessing another level of TLB cache. \\
& \\
(p/cpu\_cycles) CPU cycles & The CPU CYCLES counter increases with \\
& every clock cycle. However, it can be \\
& affected by changes in clock frequency, \\
& such as when WFI (Wait for Interrupt) \\
& or WFE (Wait for Event) \\
& instructions pause the clock. \\
& \\
(p/dtlb\_walk) Data TLB walks & Data TLB access with at least \\
& one translation table walk. \\
& \\
(p/ll\_cache\_miss\_rd) Last level cache miss reads & Last level cache miss, read \\
& (This refers to every miss in the \\
& Last level cache that occurs \\
& during a memory read operation.) \\
\hline
\end{tabular}
\end{center}
\subsubsection{Benchmarks}
\label{sec:orgddacffd}
The benchmarks are classified into 2 classes:
\begin{enumerate}
\item Micro benchmark
\label{sec:orgb329a4e}
\begin{itemize}
\item GLIBC: The Glibc benchmark evaluates the performance of
malloc and free functions in single-threaded, multi-threaded,
and emulated multi-threading scenarios using various block sizes and
allocation patterns. It simulates real-world memory usage by partially
deallocating blocks in FIFO order and fully deallocating them in LIFO order.
Results are gathered across configurations to analyze performance variations.
\item MemAccess: This benchmark by Alex Bordei evaluates the performance impact of
memory access patterns by constructing and traversing a doubly
linked list with varying working set sizes. It supports sequential or
randomized structures, optional node operations, and multithreaded
traversal using pthreads. The program dynamically allocates memory and systematically
doubles the working set size to analyze memory hierarchy behavior.
\end{itemize}
\item Macro runs
\label{sec:orga786fd0}
\begin{itemize}
\item Kmeans: Kmeans implements a parallelized K-means clustering algorithm that
assigns data points to clusters based on proximity to centroids,
iteratively updating them until convergence. The computation is
distributed across threads using the pthread library, dynamically
assigning tasks to optimize performance. Parameters like data size
and clusters are configurable, and the program ensures efficient
memory management and synchronization.
\item Richards: Richards is a task scheduling benchmark that simulates a
multitasking environment with tasks of varying types and priorities,
communicating through queued packets. The schedule function manages
task execution based on state and priority, tracking processed packets
and held tasks for performance evaluation. Configurable iterations and
timing help measure system performance and ensure correctness.
\end{itemize}
\end{enumerate}
\subsection{Results}
\label{sec:org4bdc0d9}
\begin{center}
\includegraphics[width=.9\linewidth]{./diagrams/allbenchmarks.png}
\end{center}
\begin{center}
\includegraphics[width=.9\linewidth]{./diagrams/kmeans.png}
\end{center}
\begin{center}
\includegraphics[width=.9\linewidth]{./diagrams/glibc.png}
\end{center}
\subsection{Usability}
\label{sec:org3b91bbd}
\end{document}

BIN
docs/evaluation/glibc.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

BIN
docs/evaluation/kmeans.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

BIN
docs/evaluation/loadmem.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB