From 58fea46976f9fb7eb6e2f08932823ba772ec8d08 Mon Sep 17 00:00:00 2001 From: Matt Stancliff Date: Thu, 26 Jun 2014 08:52:53 -0400 Subject: [PATCH] Allow atomic memory count update with C11 builtins MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit From mailing list post https://groups.google.com/forum/#!topic/redis-db/QLjiQe4D7LA In zmalloc.c the following primitives are currently used to synchronize access to single global variable: __sync_add_and_fetch __sync_sub_and_fetch In some architectures such as powerpc these primitives are overhead intensive. More efficient C11 __atomic builtins are available with newer GCC versions, see http://gcc.gnu.org/onlinedocs/gcc-4.8.2/gcc/_005f_005fatomic-Builtins.html#_005f_005fatomic-Builtins By substituting the following __atomic… builtins: __atomic_add_fetch __atomic_sub_fetch the performance improvement on certain architectures such as powerpc can be significant, around 10% to 15%, over the implementation using __sync builtins while there is only slight uptick on Intel architectures because it was already enforcing Intel Strongly ordered memory semantics. The selection of __atomic built-ins can be predicated on the definition of ATOMIC_RELAXED which Is available on in gcc 4.8.2 and later versions. --- src/zmalloc.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/zmalloc.c b/src/zmalloc.c index bd36654f..11616e5a 100644 --- a/src/zmalloc.c +++ b/src/zmalloc.c @@ -67,7 +67,10 @@ void zlibc_free(void *ptr) { #define free(ptr) je_free(ptr) #endif -#ifdef HAVE_ATOMIC +#if defined(__ATOMIC_RELAXED) +#define update_zmalloc_stat_add(__n) __atomic_add_fetch(&used_memory, (__n), __ATOMIC_RELAXED) +#define update_zmalloc_stat_sub(__n) __atomic_sub_fetch(&used_memory, (__n), __ATOMIC_RELAXED) +#elif defined(HAVE_ATOMIC) #define update_zmalloc_stat_add(__n) __sync_add_and_fetch(&used_memory, (__n)) #define update_zmalloc_stat_sub(__n) __sync_sub_and_fetch(&used_memory, (__n)) #else @@ -219,7 +222,7 @@ size_t zmalloc_used_memory(void) { size_t um; if (zmalloc_thread_safe) { -#ifdef HAVE_ATOMIC +#if defined(__ATOMIC_RELAXED) || defined(HAVE_ATOMIC) um = update_zmalloc_stat_add(0); #else pthread_mutex_lock(&used_memory_mutex); -- GitLab