From: Marek Olšák <marek.ol...@amd.com> More info about jemalloc: https://github.com/jemalloc/jemalloc/wiki/History
Average from 3 takes compiling Alien Isolation shaders from GLSL to GCN bytecode: glibc: 17.183s jemalloc: 15.558s diff: -9.5% The diff is -10.5% for a full shader-db run. --- TODO: The jemalloc dependency should be added to configure.ac before this. We can probably redirect all malloc/calloc/realloc/free calls in Mesa to jemalloc. We can either use _mesa_jemalloc, etc. everywhere or we can redirect calls to jemalloc using #define malloc _mesa_jemalloc, etc. Right now, I just use: export LDFLAGS=-ljemalloc src/util/jemalloc_wrapper.h | 95 +++++++++++++++++++++++++++++++++++++++++++++ src/util/ralloc.c | 7 ++-- 2 files changed, 99 insertions(+), 3 deletions(-) create mode 100644 src/util/jemalloc_wrapper.h diff --git a/src/util/jemalloc_wrapper.h b/src/util/jemalloc_wrapper.h new file mode 100644 index 0000000..d994576 --- /dev/null +++ b/src/util/jemalloc_wrapper.h @@ -0,0 +1,95 @@ +/* + * Copyright © 2016 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef JEMALLOC_WRAPPER_H +#define JEMALLOC_WRAPPER_H + +#if defined(_WIN32) || defined(WIN32) + +/* Use a fallback on Windows. */ +#include <stdlib.h> +#define _mesa_jemalloc malloc +#define _mesa_jezalloc(size) calloc(1, size) +#define _mesa_jecalloc calloc +#define _mesa_jerealloc realloc +#define _mesa_jefree free + +#else /* Linux, BSD, etc. */ + +#include "macros.h" +#include <jemalloc/jemalloc.h> + +/* Standard function names (malloc, etc.) can't be used, because glibc is + * loaded first, so libjemalloc can't override them. Instead, alternative + * jemalloc functions are used, which do the same thing. + * + * - mallocx = like malloc + * - rallocx = like realloc + * - dallocx = like free + */ + +static inline void * +_mesa_jemalloc(size_t size) +{ + if (unlikely(!size)) + size = 1; + + return mallocx(size, 0); +} + +static inline void * +_mesa_jezalloc(size_t size) +{ + if (unlikely(!size)) + size = 1; + + return mallocx(size, MALLOCX_ZERO); +} + +static inline void * +_mesa_jecalloc(size_t num, size_t size) +{ + /* TODO: + * Check for overflow if needed. + * See jemalloc, which seems to use a compatible license. + */ + return _mesa_jezalloc(num * size); +} + +static inline void * +_mesa_jerealloc(void *ptr, size_t size) +{ + if (unlikely(!size)) + size = 1; + + return rallocx(ptr, size, 0); +} + +static inline void +_mesa_jefree(void *ptr) +{ + dallocx(ptr, 0); +} + +#endif /* OS/Platform check */ +#endif /* JEMALLOC_WRAPPER_H */ diff --git a/src/util/ralloc.c b/src/util/ralloc.c index 9526011..d3897ed 100644 --- a/src/util/ralloc.c +++ b/src/util/ralloc.c @@ -33,20 +33,21 @@ #include <limits.h> #endif /* Some versions of MinGW are missing _vscprintf's declaration, although they * still provide the symbol in the import library. */ #ifdef __MINGW32__ _CRTIMP int _vscprintf(const char *format, va_list argptr); #endif #include "ralloc.h" +#include "jemalloc_wrapper.h" #ifndef va_copy #ifdef __va_copy #define va_copy(dest, src) __va_copy((dest), (src)) #else #define va_copy(dest, src) (dest) = (src) #endif #endif #define CANARY 0x5A1106 @@ -115,21 +116,21 @@ ralloc_size(const void *ctx, size_t size) * * TODO: Make ralloc_size not zero fill memory, and cleanup any code that * should instead be using rzalloc. */ return rzalloc_size(ctx, size); } void * rzalloc_size(const void *ctx, size_t size) { - void *block = calloc(1, size + sizeof(ralloc_header)); + void *block = _mesa_jezalloc(size + sizeof(ralloc_header)); ralloc_header *info; ralloc_header *parent; if (unlikely(block == NULL)) return NULL; info = (ralloc_header *) block; parent = ctx != NULL ? get_header(ctx) : NULL; add_child(parent, info); @@ -140,21 +141,21 @@ rzalloc_size(const void *ctx, size_t size) return PTR_FROM_HEADER(info); } /* helper function - assumes ptr != NULL */ static void * resize(void *ptr, size_t size) { ralloc_header *child, *old, *info; old = get_header(ptr); - info = realloc(old, size + sizeof(ralloc_header)); + info = _mesa_jerealloc(old, size + sizeof(ralloc_header)); if (info == NULL) return NULL; /* Update parent and sibling's links to the reallocated node. */ if (info != old && info->parent != NULL) { if (info->parent->child == old) info->parent->child = info; if (info->prev != NULL) @@ -248,21 +249,21 @@ unsafe_free(ralloc_header *info) while (info->child != NULL) { temp = info->child; info->child = temp->next; unsafe_free(temp); } /* Free the block itself. Call the destructor first, if any. */ if (info->destructor != NULL) info->destructor(PTR_FROM_HEADER(info)); - free(info); + _mesa_jefree(info); } void ralloc_steal(const void *new_ctx, void *ptr) { ralloc_header *info, *parent; if (unlikely(ptr == NULL)) return; -- 2.7.4 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev