From 3000b5b1f1fe44cc8a23ca34540c1de4381ada83 Mon Sep 17 00:00:00 2001 From: David Reiss Date: Mon, 31 Mar 2008 21:38:29 +0000 Subject: [PATCH] Add an experiment to measure the likeliness that realloc will avoid a copy. git-svn-id: https://svn.apache.org/repos/asf/incubator/thrift/trunk@665625 13f79535-47bb-0310-9956-ffa450edef68 --- test/cpp/realloc/Makefile | 21 ++++++++ test/cpp/realloc/realloc_test.c | 88 +++++++++++++++++++++++++++++++++ 2 files changed, 109 insertions(+) create mode 100644 test/cpp/realloc/Makefile create mode 100644 test/cpp/realloc/realloc_test.c diff --git a/test/cpp/realloc/Makefile b/test/cpp/realloc/Makefile new file mode 100644 index 00000000..57ffb87b --- /dev/null +++ b/test/cpp/realloc/Makefile @@ -0,0 +1,21 @@ +# This probably should not go into "make check", because it is an experiment, +# not a test. Specifically, it is meant to determine how likely realloc is +# to avoid a copy. This is poorly documented. + +run: realloc_test + for it in 1 4 64 ; do \ + for nb in 1 8 64 512 ; do \ + for mins in 64 512 ; do \ + for maxs in 2048 262144 ; do \ + for db in 8 64 ; do \ + ./realloc_test $$nb $$mins $$maxs $$db $$it \ + ; done \ + ; done \ + ; done \ + ; done \ + ; done \ + > raw_stats + +CFLAGS = -Wall -g -std=c99 +LDLIBS = -ldl +realloc_test: realloc_test.c diff --git a/test/cpp/realloc/realloc_test.c b/test/cpp/realloc/realloc_test.c new file mode 100644 index 00000000..7a382b1d --- /dev/null +++ b/test/cpp/realloc/realloc_test.c @@ -0,0 +1,88 @@ +#define _GNU_SOURCE +#include +#include +#include +#include + +int copies; +int non_copies; + +void *realloc(void *ptr, size_t size) { + static void *(*real_realloc)(void*, size_t) = NULL; + if (real_realloc == NULL) { + real_realloc = (void* (*) (void*, size_t)) dlsym(RTLD_NEXT, "realloc"); + } + + void *ret_ptr = (*real_realloc)(ptr, size); + + if (ret_ptr == ptr) { + non_copies++; + } else { + copies++; + } + + return ret_ptr; +} + + +struct TMemoryBuffer { + void* ptr; + int size; +}; + +int main(int argc, char *argv[]) { + int num_buffers; + int init_size; + int max_size; + int doublings; + int iterations; + + if (argc < 6 || + argc > 7 || + (num_buffers = atoi(argv[1])) == 0 || + (init_size = atoi(argv[2])) == 0 || + (max_size = atoi(argv[3])) == 0 || + init_size > max_size || + (iterations = atoi(argv[4])) == 0 || + (doublings = atoi(argv[5])) == 0 || + (argc == 7 && atoi(argv[6]) == 0)) { + fprintf(stderr, "usage: realloc_test [seed]\n"); + exit(EXIT_FAILURE); + } + + for ( int i = 0 ; i < argc ; i++ ) { + printf("%s ", argv[i]); + } + printf("\n"); + + if (argc == 7) { + srand(atoi(argv[6])); + } else { + srand(time(NULL)); + } + + struct TMemoryBuffer* buffers = calloc(num_buffers, sizeof(*buffers)); + if (buffers == NULL) abort(); + + for ( int i = 0 ; i < num_buffers ; i++ ) { + buffers[i].size = max_size; + } + + while (iterations --> 0) { + for ( int i = 0 ; i < doublings * num_buffers ; i++ ) { + struct TMemoryBuffer* buf = &buffers[rand() % num_buffers]; + buf->size *= 2; + if (buf->size <= max_size) { + buf->ptr = realloc(buf->ptr, buf->size); + } else { + free(buf->ptr); + buf->size = init_size; + buf->ptr = malloc(buf->size); + } + if (buf->ptr == NULL) abort(); + } + } + + printf("Non-copied %d/%d (%.2f%%)\n", non_copies, copies + non_copies, 100.0 * non_copies / (copies + non_copies)); + return 0; +} -- 2.17.1