diff options
| author | Florian Fischer <florian.fl.fischer@fau.de> | 2019-11-10 19:19:21 +0100 |
|---|---|---|
| committer | Florian Fischer <florian.fl.fischer@fau.de> | 2019-11-10 19:19:21 +0100 |
| commit | d28138d2425214303491f14164c482e1e83f8ca9 (patch) | |
| tree | 556d292187040c3691450aa3e7f17f158457eef5 | |
| parent | d16cc247bbf4f3cb4f9c6ce31bfe1bec4bdb8dd9 (diff) | |
| download | allocbench-d28138d2425214303491f14164c482e1e83f8ca9.tar.gz allocbench-d28138d2425214303491f14164c482e1e83f8ca9.zip | |
add some bumpptr flavors
| -rw-r--r-- | src/Makefile | 8 | ||||
| -rw-r--r-- | src/benchmark.py | 2 | ||||
| -rw-r--r-- | src/benchmarks/falsesharing.py | 46 | ||||
| -rw-r--r-- | src/benchmarks/mysql.py | 4 | ||||
| -rw-r--r-- | src/bump_alloc.h | 54 | ||||
| -rw-r--r-- | src/bumpptr_alloc.c | 40 | ||||
| -rw-r--r-- | src/bumpptr_alloc_always_align.c | 171 | ||||
| -rw-r--r-- | src/bumpptr_alloc_single_tsd.c | 136 |
8 files changed, 416 insertions, 45 deletions
diff --git a/src/Makefile b/src/Makefile index 6a46af9..48b35f9 100644 --- a/src/Makefile +++ b/src/Makefile @@ -25,6 +25,14 @@ $(OBJDIR)/allocators/bumpptr_alloc.so: bumpptr_alloc.c Makefile @if test \( ! \( -d $(@D) \) \) ;then mkdir -p $(@D);fi $(CC) $(LDFLAGS) -shared -DMEMSIZE=$(MEMSIZE) $(CFLAGS) -o $@ $< +$(OBJDIR)/allocators/bumpptr_alloc_always_align.so: bumpptr_alloc_always_align.c.c Makefile + @if test \( ! \( -d $(@D) \) \) ;then mkdir -p $(@D);fi + $(CC) $(LDFLAGS) -shared -DMEMSIZE=$(MEMSIZE) $(CFLAGS) -o $@ $< + +$(OBJDIR)/allocators/bumpptr_alloc_single_tsd.so: bumpptr_alloc_single_tsd.c.c Makefile + @if test \( ! \( -d $(@D) \) \) ;then mkdir -p $(@D);fi + $(CC) $(LDFLAGS) -shared -DMEMSIZE=$(MEMSIZE) $(CFLAGS) -o $@ $< + $(OBJDIR)/allocators/speedymalloc.so: speedymalloc.c Makefile @if test \( ! \( -d $(@D) \) \) ;then mkdir -p $(@D);fi $(CC) $(LDFLAGS) -shared -DMEMSIZE=$(MEMSIZE) $(CFLAGS) -o $@ $< diff --git a/src/benchmark.py b/src/benchmark.py index d77b09d..3e2a61c 100644 --- a/src/benchmark.py +++ b/src/benchmark.py @@ -667,7 +667,7 @@ class Benchmark: plt.legend(loc="best") if not autoticks: - plt.xticks(x_vals, args[loose_arg]) + plt.xticks(x_vals, args[loose_arg], rotation=90) plt.xlabel(eval(xlabel)) plt.ylabel(eval(ylabel)) plt.title(eval(title)) diff --git a/src/benchmarks/falsesharing.py b/src/benchmarks/falsesharing.py index 93c2fe9..cc5e0e3 100644 --- a/src/benchmarks/falsesharing.py +++ b/src/benchmarks/falsesharing.py @@ -53,38 +53,35 @@ class BenchmarkFalsesharing(Benchmark): result["time"] = TIME_RE.match(stdout).group("time") def summary(self): - # Speedup thrash args = self.results["args"] nthreads = args["threads"] allocators = self.results["allocators"] + # calculate relevant datapoints: speedup, l1-cache-misses for bench in self.results["args"]["bench"]: for allocator in allocators: - y_vals = [] - - single_threaded_perm = self.Perm(bench=bench, threads=1) - single_threaded = np.mean([float(m["time"]) - for m in self.results[allocator][single_threaded_perm]]) + sequential_perm = self.Perm(bench=bench, threads=1) for perm in self.iterate_args_fixed({"bench": bench}, args=args): + speedup = [] + l1chache_misses = [] + for i, measure in enumerate(self.results[allocator][perm]): + sequential_time = float(self.results[allocator][sequential_perm][i]["time"]) + measure["speedup"] = float(measure["time"]) / sequential_time + measure["l1chache_misses"] = eval("({L1-dcache-load-misses}/{L1-dcache-loads})*100".format(**measure)) + + # delete and recalculate stats + del self.results["stats"] + self.calc_desc_statistics() + + self.plot_fixed_arg("{speedup}", + ylabel="'Speedup'", + title="'Speedup: ' + arg + ' ' + str(arg_value)", + filepostfix="speedup", + autoticks=False, + fixed=["bench"]) - data = [float(m["time"]) for m in self.results[allocator][perm]] - - speedup = single_threaded / np.mean(data) - self.results["stats"][allocator][perm]["mean"]["speedup"] = speedup - y_vals.append(speedup) - - plt.plot(nthreads, y_vals, marker='.', linestyle='-', - label=allocator, color=allocators[allocator]["color"]) - - plt.legend() - plt.xlabel("threads") - plt.ylabel("speedup") - plt.title(bench + " speedup") - plt.savefig(f"{self.name}.{bench}.{summary_file_ext}") - plt.clf() - - self.plot_fixed_arg("({L1-dcache-load-misses}/{L1-dcache-loads})*100", + self.plot_fixed_arg("{l1chache_misses}", ylabel="'l1 cache misses in %'", title="'cache misses: ' + arg + ' ' + str(arg_value)", filepostfix="l1-misses", @@ -103,5 +100,8 @@ class BenchmarkFalsesharing(Benchmark): "sort":">"}], filepostfix="speedup.table") + self.export_stats_to_csv("speedup", "time") + self.export_stats_to_csv("l1chache_misses", "l1-misses") + falsesharing = BenchmarkFalsesharing() diff --git a/src/benchmarks/mysql.py b/src/benchmarks/mysql.py index c7519c5..2889497 100644 --- a/src/benchmarks/mysql.py +++ b/src/benchmarks/mysql.py @@ -86,8 +86,8 @@ from src.benchmark import Benchmark import src.facter from src.util import print_status, print_debug, print_info2 -MYSQL_USER = "root" -RUN_TIME = 300 +MYSQL_USER = "fischerling" +RUN_TIME = 10 TABLES = 5 PREPARE_CMD = (f"sysbench oltp_read_only --db-driver=mysql --mysql-user={MYSQL_USER} " diff --git a/src/bump_alloc.h b/src/bump_alloc.h new file mode 100644 index 0000000..bc9cbac --- /dev/null +++ b/src/bump_alloc.h @@ -0,0 +1,54 @@ +#include <assert.h> +#include <stddef.h> /* NULL, size_t */ +#include <stdint.h> /* uintptr_t */ + +#ifndef MEMSIZE +#define MEMSIZE 1024*4*1024*1024l +#endif + +#define unlikely(x) __builtin_expect((x),0) + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + uintptr_t end = 0; + uintptr_t ptr = 0; +} bumpptr_t; + +__thread bumpptr_t* tsd = NULL; + +inline void init_tsd() { + void* mem_start = mmap(NULL, MEMSIZE, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); + if(mem_start == MAP_FAILED) { + perror("mmap"); + return NULL; + } + tsd = (bumpptr_t*)mem_start; + tsd->ptr = (uintptr_t)mem_start + sizeof(bumpptr_t); + tsd->end = (uintptr_t)mem_start + MEMSIZE; +} + +inline void* bump_up(size_t size, size_t align) { + assert(align % 2 == 0); + + if (unlikely(tsd == NULL)) { + init_tsd(); + } + + // align ptr; + uintptr_t aligned = (tsd->ptr + align - 1) & ~(align - 1); + + uintptr_t new_ptr = aligned + size; + if (new_ptr > mem_end) + return NULL; + else { + tsd->ptr = new_ptr; + return (void*)aligned; + } +} + +#ifdef __cplusplus +} +#endif diff --git a/src/bumpptr_alloc.c b/src/bumpptr_alloc.c index 3985904..6cb82df 100644 --- a/src/bumpptr_alloc.c +++ b/src/bumpptr_alloc.c @@ -1,3 +1,4 @@ +#include <assert.h> #include <errno.h> #include <stddef.h> /* NULL, size_t */ #include <stdint.h> /* uintptr_t */ @@ -19,11 +20,12 @@ extern "C" { #endif __thread void* mem_start = NULL; -__thread void* mem_end = NULL; - +__thread uintptr_t mem_end = 0; __thread uintptr_t ptr = 0; -void* malloc(size_t size) { +inline void* bump_up(size_t size, size_t align) { + assert(align % 2 == 0); + if (unlikely(mem_start == NULL)) { mem_start = mmap(NULL, MEMSIZE, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); if(mem_start == MAP_FAILED) { @@ -31,17 +33,23 @@ void* malloc(size_t size) { return NULL; } ptr = (uintptr_t)mem_start; + mem_end = ptr + MEMSIZE; } // align ptr; - if (ptr % MIN_ALIGNMENT != 0) { - size_t mask = MIN_ALIGNMENT -1; - ptr = (ptr + mask) & ~mask; + uintptr_t aligned = (ptr + align - 1) & ~(align - 1); + + uintptr_t new_ptr = aligned + size; + if (new_ptr > mem_end) + return NULL; + else { + ptr = new_ptr; + return (void*)aligned; } +} - void* ret = (void*)ptr; - ptr += size; - return ret; +void* malloc(size_t size) { + return bump_up(size, MIN_ALIGNMENT); } void free(__attribute__ ((unused)) void* ptr) { @@ -51,20 +59,14 @@ void* realloc(void* ptr, size_t size) { if(ptr == NULL) return malloc(size); - if(size == 0) - return NULL; - - void* new_ptr = malloc(size); + void* new_ptr = bump_up(size, MIN_ALIGNMENT); // this may copies to much memcpy(new_ptr, ptr, size); return new_ptr; } void* memalign(size_t alignment, size_t size) { - // align ptr to alignment and malloc - size_t mask = alignment - 1; - ptr = (ptr + mask) & ~mask; - return malloc(size); + return bump_up(size, alignment); } int posix_memalign(void **memptr, size_t alignment, size_t size) @@ -89,7 +91,7 @@ int posix_memalign(void **memptr, size_t alignment, size_t size) return 0; } - out = memalign(alignment, size); + out = bump_up(size, alignment); if(out == NULL) { return 12; } @@ -107,7 +109,7 @@ void* calloc(size_t nmemb, size_t size) return NULL; } - out = malloc(fullsize); + out = bump_up(fullsize, MIN_ALIGNMENT); if(out == NULL) { return NULL; } diff --git a/src/bumpptr_alloc_always_align.c b/src/bumpptr_alloc_always_align.c new file mode 100644 index 0000000..6cb82df --- /dev/null +++ b/src/bumpptr_alloc_always_align.c @@ -0,0 +1,171 @@ +#include <assert.h> +#include <errno.h> +#include <stddef.h> /* NULL, size_t */ +#include <stdint.h> /* uintptr_t */ +#include <stdio.h> /* uintptr_t */ +#include <unistd.h> /* sysconf(_SC_PAGESIZE) */ +#include <string.h> /* memset */ +#include <sys/mman.h> /* memset */ + +#define MIN_ALIGNMENT 16 + +#ifndef MEMSIZE +#define MEMSIZE 1024*4*1024*1024l +#endif + +#define unlikely(x) __builtin_expect((x),0) + +#ifdef __cplusplus +extern "C" { +#endif + +__thread void* mem_start = NULL; +__thread uintptr_t mem_end = 0; +__thread uintptr_t ptr = 0; + +inline void* bump_up(size_t size, size_t align) { + assert(align % 2 == 0); + + if (unlikely(mem_start == NULL)) { + mem_start = mmap(NULL, MEMSIZE, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); + if(mem_start == MAP_FAILED) { + perror("mmap"); + return NULL; + } + ptr = (uintptr_t)mem_start; + mem_end = ptr + MEMSIZE; + } + + // align ptr; + uintptr_t aligned = (ptr + align - 1) & ~(align - 1); + + uintptr_t new_ptr = aligned + size; + if (new_ptr > mem_end) + return NULL; + else { + ptr = new_ptr; + return (void*)aligned; + } +} + +void* malloc(size_t size) { + return bump_up(size, MIN_ALIGNMENT); +} + +void free(__attribute__ ((unused)) void* ptr) { +} + +void* realloc(void* ptr, size_t size) { + if(ptr == NULL) + return malloc(size); + + void* new_ptr = bump_up(size, MIN_ALIGNMENT); + // this may copies to much + memcpy(new_ptr, ptr, size); + return new_ptr; +} + +void* memalign(size_t alignment, size_t size) { + return bump_up(size, alignment); +} + +int posix_memalign(void **memptr, size_t alignment, size_t size) +{ + void *out; + + if(memptr == NULL) { + return 22; + } + + if((alignment % sizeof(void*)) != 0) { + return 22; + } + + /* if not power of two */ + if(!((alignment != 0) && !(alignment & (alignment - 1)))) { + return 22; + } + + if(size == 0) { + *memptr = NULL; + return 0; + } + + out = bump_up(size, alignment); + if(out == NULL) { + return 12; + } + + *memptr = out; + return 0; +} + +void* calloc(size_t nmemb, size_t size) +{ + void *out; + size_t fullsize = nmemb * size; + + if((size != 0) && ((fullsize / size) != nmemb)) { + return NULL; + } + + out = bump_up(fullsize, MIN_ALIGNMENT); + if(out == NULL) { + return NULL; + } + + memset(out, 0, fullsize); + return out; +} + +void* valloc(size_t size) +{ + long ret = sysconf(_SC_PAGESIZE); + if(ret == -1) { + return NULL; + } + + return memalign(ret, size); +} + +void* pvalloc(size_t size) +{ + size_t ps, rem, allocsize; + + long ret = sysconf(_SC_PAGESIZE); + if(ret == -1) { + return NULL; + } + + ps = ret; + rem = size % ps; + allocsize = size; + if(rem != 0) { + allocsize = ps + (size - rem); + } + + return memalign(ps, allocsize); +} + +void* aligned_alloc(size_t alignment, size_t size) +{ + if(alignment > size) { + return NULL; + } + + if((size % alignment) != 0) { + return NULL; + } + + return memalign(alignment, size); +} + +int malloc_stats() { + fprintf(stderr, "Bump pointer allocator by muhq\n"); + fprintf(stderr, "Memsize: %zu, start address: %p, bump pointer %p\n", MEMSIZE, mem_start, ptr); + return 0; +} + +#ifdef __cplusplus +} +#endif diff --git a/src/bumpptr_alloc_single_tsd.c b/src/bumpptr_alloc_single_tsd.c new file mode 100644 index 0000000..7c51bae --- /dev/null +++ b/src/bumpptr_alloc_single_tsd.c @@ -0,0 +1,136 @@ +#include <errno.h> /* TODO: set errno */ +#include <stddef.h> /* NULL, size_t */ +#include <stdint.h> /* uintptr_t */ +#include <stdio.h> /* fprintf */ +#include <unistd.h> /* sysconf(_SC_PAGESIZE) */ +#include <string.h> /* memset */ + +#include "bump_alloc.h" + +#define MIN_ALIGNMENT 16 + +#ifdef __cplusplus +extern "C" { +#endif + +void* malloc(size_t size) { + return bump_up(size, MIN_ALIGNMENT); +} + +void free(__attribute__ ((unused)) void* ptr) { +} + +void* realloc(void* ptr, size_t size) { + if(ptr == NULL) + return malloc(size); + + void* new_ptr = bump_up(size, MIN_ALIGNMENT); + // this may copies to much + memcpy(new_ptr, ptr, size); + return new_ptr; +} + +void* memalign(size_t alignment, size_t size) { + return bump_up(size, alignment); +} + +int posix_memalign(void **memptr, size_t alignment, size_t size) +{ + void *out; + + if(memptr == NULL) { + return 22; + } + + if((alignment % sizeof(void*)) != 0) { + return 22; + } + + /* if not power of two */ + if(!((alignment != 0) && !(alignment & (alignment - 1)))) { + return 22; + } + + if(size == 0) { + *memptr = NULL; + return 0; + } + + out = bump_up(size, alignment); + if(out == NULL) { + return 12; + } + + *memptr = out; + return 0; +} + +void* calloc(size_t nmemb, size_t size) +{ + void *out; + size_t fullsize = nmemb * size; + + if((size != 0) && ((fullsize / size) != nmemb)) { + return NULL; + } + + out = bump_up(fullsize, MIN_ALIGNMENT); + if(out == NULL) { + return NULL; + } + + memset(out, 0, fullsize); + return out; +} + +void* valloc(size_t size) +{ + long ret = sysconf(_SC_PAGESIZE); + if(ret == -1) { + return NULL; + } + + return memalign(ret, size); +} + +void* pvalloc(size_t size) +{ + size_t ps, rem, allocsize; + + long ret = sysconf(_SC_PAGESIZE); + if(ret == -1) { + return NULL; + } + + ps = ret; + rem = size % ps; + allocsize = size; + if(rem != 0) { + allocsize = ps + (size - rem); + } + + return memalign(ps, allocsize); +} + +void* aligned_alloc(size_t alignment, size_t size) +{ + if(alignment > size) { + return NULL; + } + + if((size % alignment) != 0) { + return NULL; + } + + return memalign(alignment, size); +} + +int malloc_stats() { + fprintf(stderr, "Bump pointer allocator by muhq\n"); + fprintf(stderr, "Memsize: %zu, start address: %p, bump pointer %p\n", MEMSIZE, mem_start, ptr); + return 0; +} + +#ifdef __cplusplus +} +#endif |
