added evaluation docs
3
.vscode/settings.json
vendored
@@ -54,7 +54,8 @@
|
||||
"limits": "cpp",
|
||||
"ratio": "cpp",
|
||||
"tuple": "cpp",
|
||||
"variant": "cpp"
|
||||
"variant": "cpp",
|
||||
"stddef.h": "c"
|
||||
},
|
||||
"C_Cpp.errorSquiggles": "disabled"
|
||||
}
|
||||
@@ -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
|
||||
// =====================================================================
|
||||
|
||||
@@ -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) );
|
||||
|
||||
@@ -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_
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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_
|
||||
|
||||
|
||||
|
||||
@@ -184,7 +184,7 @@ int main(argc, argv)
|
||||
{
|
||||
|
||||
|
||||
INITREGULARALLOC(0);
|
||||
// INITREGULARALLOC(0);
|
||||
|
||||
unsigned m = 0, k = 0;
|
||||
unsigned maxCount = 1<<30, count, maxk = 0;
|
||||
|
||||
@@ -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_
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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_
|
||||
|
||||
|
||||
|
||||
31
docs/evaluation/#evaluation-plan.org#
Normal 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.
|
||||
BIN
docs/evaluation/allbenchmarks.png
Normal file
|
After Width: | Height: | Size: 51 KiB |
BIN
docs/evaluation/diagrams/allbenchmarks.png
Normal file
|
After Width: | Height: | Size: 51 KiB |
BIN
docs/evaluation/diagrams/glibc.png
Normal file
|
After Width: | Height: | Size: 60 KiB |
BIN
docs/evaluation/diagrams/kmeans.png
Normal file
|
After Width: | Height: | Size: 84 KiB |
BIN
docs/evaluation/diagrams/loadmem.png
Normal file
|
After Width: | Height: | Size: 42 KiB |
31
docs/evaluation/evaluation-plan.org
Normal 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.
|
||||
6
docs/evaluation/evaluation.bib
Normal 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},
|
||||
}
|
||||
6
docs/evaluation/evaluation.bib~
Normal 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},
|
||||
}
|
||||
207
docs/evaluation/evaluation.org
Normal 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
|
||||
222
docs/evaluation/evaluation.org~
Normal 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
|
||||
BIN
docs/evaluation/evaluation.pdf
Normal file
201
docs/evaluation/evaluation.tex
Normal 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
|
After Width: | Height: | Size: 60 KiB |
BIN
docs/evaluation/graphs/allbenchmarks.png
Normal file
|
After Width: | Height: | Size: 51 KiB |
BIN
docs/evaluation/graphs/glibc.png
Normal file
|
After Width: | Height: | Size: 60 KiB |
BIN
docs/evaluation/graphs/kmeans.png
Normal file
|
After Width: | Height: | Size: 84 KiB |
BIN
docs/evaluation/kmeans.png
Normal file
|
After Width: | Height: | Size: 84 KiB |
BIN
docs/evaluation/loadmem.png
Normal file
|
After Width: | Height: | Size: 42 KiB |