From b3427fb76390b0074f0e702cc16604a2d8df327a Mon Sep 17 00:00:00 2001 From: Florian Fischer Date: Mon, 9 Jul 2018 17:10:38 +0200 Subject: add loop benchmark abd Makefile --- Makefile | 55 ++++++++++++++++++++++++++++++ bench_loop.c | 109 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 164 insertions(+) create mode 100644 Makefile create mode 100644 bench_loop.c diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..5614832 --- /dev/null +++ b/Makefile @@ -0,0 +1,55 @@ +.PHONY: all clean bench + +.DEFAULT_GOAL = all + +C_SOURCES = $(shell find . -name "*.c") +CC_SOURCES = $(shell find . -name "*.cc") + +VERBOSE = +OBJDIR = ./build + +CC = gcc +CXX = g++ + +WARNFLAGS = -Wall -Wextra +COMMONFLAGS = -fno-builtin -fPIC -DPIC -pthread +OPTFLAGS = -O3 -DNDEBUG +#OPTFLAGS = -O0 -g3 + +CXXFLAGS = -std=c++11 -I. $(OPTFLAGS) $(WARNFLAGS) $(COMMONFLAGS) -fno-exceptions +CFLAGS = -I. $(OPTFLAGS) $(WARNFLAGS) $(COMMONFLAGS) +#LDFLAGS= -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-free + +VPATH = $(sort $(dir $(C_SOURCES) $(CC_SOURCES))) + +OBJECTS = $(notdir $(CC_SOURCES:.cc=.o)) $(notdir $(C_SOURCES:.c=.o)) +OBJPRE = $(addprefix $(OBJDIR)/,$(OBJECTS)) +MAKEFILE_LIST = Makefile + +all: $(OBJDIR)/bench_loop + +bench: all + @if test \( ! \( -d bench.d \) \) ;then mkdir -p bench.d;fi + bash -c "./bench.py" + +$(OBJDIR)/bench_loop: $(OBJDIR)/bench_loop.o + @echo "ld $@" + @if test \( ! \( -d $(@D) \) \) ;then mkdir -p $(@D);fi + $(VERBOSE) $(CC) -pthread -o $@ $^ + +$(OBJDIR)/%.o : %.c $(MAKEFILE_LIST) + @echo "cc $@" + @if test \( ! \( -d $(@D) \) \) ;then mkdir -p $(@D);fi + $(VERBOSE) $(CC) -c $(CFLAGS) -o $@ $< + +$(OBJDIR)/%.o : %.cc $(MAKEFILE_LIST) + @echo "cxx $@" + @if test \( ! \( -d $(@D) \) \) ;then mkdir -p $(@D);fi + $(VERBOSE) $(CXX) -c $(CXXFLAGS) -o $@ $< + +clean: + @echo "rm $(OBJDIR)" + $(VERBOSE) rm -rf $(OBJDIR) + @echo "rm $(DEPDIR)" + $(VERBOSE) rm -rf $(DEPDIR) + diff --git a/bench_loop.c b/bench_loop.c new file mode 100644 index 0000000..03eac25 --- /dev/null +++ b/bench_loop.c @@ -0,0 +1,109 @@ +#include +#include +#include +#include +#include + + +static size_t _rand() { + static __thread size_t seed = 123456789; + size_t a = 1103515245; + size_t c = 12345; + size_t m = 1 << 31; + seed = (a * seed + c) % m; + return seed; +} + +/* +* Available Benchmarks: +* 1.x: do malloc()/free() in a loop +* 1: simple loop +* 1.1: keep num_kept_allocations befor freeing +* 1.2: keep num_kept_allocations then free all stored +*/ + +typedef struct ThreadArgs { + double benchmark; + int allocations; + int num_kept_allocations; + int max_size; +} ThreadArgs; + +static void* malloc_then_write(size_t size) { + void* ptr = malloc(size); + // Write to ptr + *((char*)ptr) = '!'; + return ptr; +} + +static void read_then_free(void* ptr) { + // Read before free + char s = *((char*)ptr); + free(ptr); +} +static void* test_thread_func(void* arg) { + ThreadArgs* args = (ThreadArgs*)arg; + void** ptrs = (void**)calloc(args->num_kept_allocations, sizeof(void*)); + + for(int i = 0; i < args->allocations; i++) { + int pos = i % args->num_kept_allocations; + + if (args->benchmark == 1.1) { + if (i >= args->num_kept_allocations) { + read_then_free(ptrs[pos]); + } + } + + if (args->benchmark == 1.2) { + if (pos == 0 && ptrs[pos] != NULL) { + for (size_t y = 0; y < args->num_kept_allocations; y++) { + read_then_free(ptrs[y]); + } + } + } + + ptrs[pos] = malloc_then_write((_rand() % args->max_size) + 1); + + if (args->benchmark == 1.0) { + read_then_free(ptrs[pos]); + } + } + return NULL; +} + +int main(int argc, char* argv[]) { + pthread_t* threads; + int num_threads; + struct ThreadArgs thread_args; + + if (argc < 6) { + fprintf(stderr, "Usage: %s \n", argv[0]); + return 1; + } + + thread_args.benchmark = atof(argv[1]); + num_threads = atoi(argv[2]); + thread_args.allocations = atoi(argv[3]); + thread_args.max_size = atoi(argv[4]); + thread_args.num_kept_allocations = atoi(argv[5]); + + threads = (pthread_t*)malloc(num_threads * sizeof(pthread_t)); + + for (int i = 0; i < num_threads; i++) { + if (0 != pthread_create(&threads[i], NULL, test_thread_func, &thread_args)) { + return 1; + } + } + + for(int i = 0; i < num_threads; i++) { + if (0 != pthread_join(threads[i], NULL)) { + return 1; + } + } + +#ifndef NSTATS + FILE* f = fopen("stats", "w"); + malloc_info(0, f); + fclose(f); +#endif +} -- cgit v1.2.3