[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [59281] trunk/blender: Speedup for guarded allocator

Sergey Sharybin sergey.vfx at gmail.com
Mon Aug 19 12:51:41 CEST 2013


Revision: 59281
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=59281
Author:   nazgul
Date:     2013-08-19 10:51:40 +0000 (Mon, 19 Aug 2013)
Log Message:
-----------
Speedup for guarded allocator

- Re-arrange locks, so no actual memory allocation
  (which is relatively slow) happens from inside
  the lock. operation system will take care of locks
  which might be needed there on it's own.

- Use spin lock instead of mutex, since it's just
  list operations happens from inside lock, no need
  in mutex here.

- Use atomic operations for memory in use and total
  used blocks counters.

This makes guarded allocator almost the same speed
as non-guarded one in files from Tube project.

There're still MemHead/MemTail overhead which might
be bad for CPU cache utilization

Modified Paths:
--------------
    trunk/blender/intern/atomic/atomic_ops.h
    trunk/blender/intern/guardedalloc/CMakeLists.txt
    trunk/blender/intern/guardedalloc/SConscript
    trunk/blender/intern/guardedalloc/intern/mallocn.c
    trunk/blender/source/blender/blenlib/BLI_threads.h
    trunk/blender/source/blender/blenlib/intern/threads.c
    trunk/blender/source/blender/makesdna/intern/CMakeLists.txt
    trunk/blender/source/blender/makesdna/intern/SConscript
    trunk/blender/source/blender/makesrna/SConscript
    trunk/blender/source/blender/makesrna/intern/CMakeLists.txt
    trunk/blender/source/blender/windowmanager/intern/wm_init_exit.c
    trunk/blender/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp

Property Changed:
----------------
    trunk/blender/
    trunk/blender/source/blender/editors/interface/interface.c
    trunk/blender/source/blender/editors/space_outliner/


Property changes on: trunk/blender
___________________________________________________________________
Modified: svn:mergeinfo
   - /branches/ge_dev:58091-58422
/branches/ge_harmony:42255,42279-42282,42286,42302,42338,42349,42616,42620,42698-42699,42739,42753,42773-42774,42832,44568,44597-44598,44793-44794
/branches/soc-2011-cucumber:37517,38166-38167,38177,38179-38180,38187,38242,38384,38387,38403-38404,38407,38968,38970,38973,39045,40845,42997-42998,43439
/branches/soc-2011-tomato:42376,42378-42379,42383,42385,42395,42397-42400,42407,42411,42418,42443-42444,42446,42467,42472,42486,42650-42652,42654-42655,42709-42710,42733-42734,42801,43872,44130,44141,44147-44149,44151-44152,44229-44230,45623-45625,46037,48089,48092,48551-48552,48679,48790,48792-48793,49076,49087,49292,49294,49466,49894,50052,50126,52854-52856,54573,58822,58989
/branches/soc-2013-depsgraph_mt:57516,57900,57939-57940,57945,57958-57961,58151,58155-58156,58169,58277-58279,58282-58283,58711,58787,58789,58796,59086-59087,59259
/branches/soc-2013-dingto:57424,57487,57507,57525,57599,57670,57918-57919,57981,58091,58245,58253,58587,58772,58774-58775,58828,58835,59032
/tags/blender-2.67b-release/blender:57122
   + /branches/ge_dev:58091-58422
/branches/ge_harmony:42255,42279-42282,42286,42302,42338,42349,42616,42620,42698-42699,42739,42753,42773-42774,42832,44568,44597-44598,44793-44794
/branches/soc-2011-cucumber:37517,38166-38167,38177,38179-38180,38187,38242,38384,38387,38403-38404,38407,38968,38970,38973,39045,40845,42997-42998,43439
/branches/soc-2011-tomato:42376,42378-42379,42383,42385,42395,42397-42400,42407,42411,42418,42443-42444,42446,42467,42472,42486,42650-42652,42654-42655,42709-42710,42733-42734,42801,43872,44130,44141,44147-44149,44151-44152,44229-44230,45623-45625,46037,48089,48092,48551-48552,48679,48790,48792-48793,49076,49087,49292,49294,49466,49894,50052,50126,52854-52856,54573,58822,58989
/branches/soc-2013-depsgraph_mt:57516,57900,57939-57940,57945,57958-57961,58151,58155-58156,58169,58277-58279,58282-58283,58711,58787,58789,58796,59086-59087,59163,59166,59170,59259
/branches/soc-2013-dingto:57424,57487,57507,57525,57599,57670,57918-57919,57981,58091,58245,58253,58587,58772,58774-58775,58828,58835,59032
/tags/blender-2.67b-release/blender:57122

Modified: trunk/blender/intern/atomic/atomic_ops.h
===================================================================
--- trunk/blender/intern/atomic/atomic_ops.h	2013-08-19 10:44:18 UTC (rev 59280)
+++ trunk/blender/intern/atomic/atomic_ops.h	2013-08-19 10:51:40 UTC (rev 59281)
@@ -44,7 +44,8 @@
 #  endif
 #endif
 
-#if defined(_M_X64) || defined(__amd64__) || defined(__x86_64__)
+/* TODO(sergey): check on other 64bit platforms. */
+#if defined(_M_X64) || defined(_M_AMD64) || defined(__amd64__) || defined(__x86_64__)
 #  define LG_SIZEOF_PTR 3
 #  define LG_SIZEOF_INT 3
 #else

Modified: trunk/blender/intern/guardedalloc/CMakeLists.txt
===================================================================
--- trunk/blender/intern/guardedalloc/CMakeLists.txt	2013-08-19 10:44:18 UTC (rev 59280)
+++ trunk/blender/intern/guardedalloc/CMakeLists.txt	2013-08-19 10:51:40 UTC (rev 59281)
@@ -25,6 +25,7 @@
 
 set(INC
 	.
+	../atomic
 )
 
 set(INC_SYS

Modified: trunk/blender/intern/guardedalloc/SConscript
===================================================================
--- trunk/blender/intern/guardedalloc/SConscript	2013-08-19 10:44:18 UTC (rev 59280)
+++ trunk/blender/intern/guardedalloc/SConscript	2013-08-19 10:51:40 UTC (rev 59281)
@@ -38,6 +38,6 @@
     sources.append('cpp/mallocn.cpp')
     defs.append('WITH_CXX_GUARDEDALLOC')
 
-incs = '.'
+incs = '. ../atomic'
 
 env.BlenderLib ('bf_intern_guardedalloc', sources, Split(incs), defs, libtype=['intern','player'], priority = [5,150] )

Modified: trunk/blender/intern/guardedalloc/intern/mallocn.c
===================================================================
--- trunk/blender/intern/guardedalloc/intern/mallocn.c	2013-08-19 10:44:18 UTC (rev 59280)
+++ trunk/blender/intern/guardedalloc/intern/mallocn.c	2013-08-19 10:51:40 UTC (rev 59281)
@@ -53,6 +53,8 @@
 /* should always be defined except for experimental cases */
 #ifdef WITH_GUARDEDALLOC
 
+#include "atomic_ops.h"
+
 /* Blame Microsoft for LLP64 and no inttypes.h, quick workaround needed: */
 #if defined(WIN64)
 #  define SIZET_FORMAT "%I64u"
@@ -210,8 +212,8 @@
 /* --------------------------------------------------------------------- */
 	
 
-static volatile int totblock = 0;
-static volatile uintptr_t mem_in_use = 0, mmap_in_use = 0, peak_mem = 0;
+static unsigned int totblock = 0;
+static size_t mem_in_use = 0, mmap_in_use = 0, peak_mem = 0;
 
 static volatile struct localListBase _membase;
 static volatile struct localListBase *membase = &_membase;
@@ -493,31 +495,29 @@
 
 	memt = (MemTail *)(((char *) memh) + sizeof(MemHead) + len);
 	memt->tag3 = MEMTAG3;
-	
+
+	atomic_add_u(&totblock, 1);
+	atomic_add_z(&mem_in_use, len);
+
+	mem_lock_thread();
 	addtail(membase, &memh->next);
 	if (memh->next) {
 		memh->nextname = MEMNEXT(memh->next)->name;
 	}
-	
-	totblock++;
-	mem_in_use += len;
-
 	peak_mem = mem_in_use > peak_mem ? mem_in_use : peak_mem;
+	mem_unlock_thread();
 }
 
 void *MEM_mallocN(size_t len, const char *str)
 {
 	MemHead *memh;
 
-	mem_lock_thread();
-
 	len = (len + 3) & ~3;   /* allocate in units of 4 */
 	
 	memh = (MemHead *)malloc(len + sizeof(MemHead) + sizeof(MemTail));
 
 	if (memh) {
 		make_memhead_header(memh, len, str);
-		mem_unlock_thread();
 		if (malloc_debug_memset && len)
 			memset(memh + 1, 255, len);
 
@@ -528,7 +528,6 @@
 #endif
 		return (++memh);
 	}
-	mem_unlock_thread();
 	print_error("Malloc returns null: len=" SIZET_FORMAT " in %s, total %u\n",
 	            SIZET_ARG(len), str, (unsigned int) mem_in_use);
 	return NULL;
@@ -538,15 +537,12 @@
 {
 	MemHead *memh;
 
-	mem_lock_thread();
-
 	len = (len + 3) & ~3;   /* allocate in units of 4 */
 
 	memh = (MemHead *)calloc(len + sizeof(MemHead) + sizeof(MemTail), 1);
 
 	if (memh) {
 		make_memhead_header(memh, len, str);
-		mem_unlock_thread();
 #ifdef DEBUG_MEMCOUNTER
 		if (_mallocn_count == DEBUG_MEMCOUNTER_ERROR_VAL)
 			memcount_raise(__func__);
@@ -554,7 +550,6 @@
 #endif
 		return (++memh);
 	}
-	mem_unlock_thread();
 	print_error("Calloc returns null: len=" SIZET_FORMAT " in %s, total %u\n",
 	            SIZET_ARG(len), str, (unsigned int) mem_in_use);
 	return NULL;
@@ -565,8 +560,6 @@
 {
 	MemHead *memh;
 
-	mem_lock_thread();
-	
 	len = (len + 3) & ~3;   /* allocate in units of 4 */
 
 	memh = mmap(NULL, len + sizeof(MemHead) + sizeof(MemTail),
@@ -575,7 +568,8 @@
 	if (memh != (MemHead *)-1) {
 		make_memhead_header(memh, len, str);
 		memh->mmap = 1;
-		mmap_in_use += len;
+		atomic_add_z(&mmap_in_use, len);
+		mem_lock_thread();
 		peak_mem = mmap_in_use > peak_mem ? mmap_in_use : peak_mem;
 		mem_unlock_thread();
 #ifdef DEBUG_MEMCOUNTER
@@ -586,7 +580,6 @@
 		return (++memh);
 	}
 	else {
-		mem_unlock_thread();
 		print_error("Mapalloc returns null, fallback to regular malloc: "
 		            "len=" SIZET_FORMAT " in %s, total %u\n",
 		            SIZET_ARG(len), str, (unsigned int) mmap_in_use);
@@ -844,7 +837,6 @@
 		return;
 	}
 
-	mem_lock_thread();
 	if ((memh->tag1 == MEMTAG1) &&
 	    (memh->tag2 == MEMTAG2) &&
 	    ((memh->len & 0x3) == 0))
@@ -858,8 +850,6 @@
 			/* after tags !!! */
 			rem_memblock(memh);
 
-			mem_unlock_thread();
-
 			return;
 		}
 		MemorY_ErroR(memh->name, "end corrupt");
@@ -869,7 +859,9 @@
 		}
 	}
 	else {
+		mem_lock_thread();
 		name = check_memlist(memh);
+		mem_unlock_thread();
 		if (name == NULL)
 			MemorY_ErroR("free", "pointer not in memlist");
 		else
@@ -879,8 +871,6 @@
 	totblock--;
 	/* here a DUMP should happen */
 
-	mem_unlock_thread();
-
 	return;
 }
 
@@ -927,6 +917,7 @@
 
 static void rem_memblock(MemHead *memh)
 {
+	mem_lock_thread();
 	remlink(membase, &memh->next);
 	if (memh->prev) {
 		if (memh->next)
@@ -934,9 +925,10 @@
 		else
 			MEMNEXT(memh->prev)->nextname = NULL;
 	}
+	mem_unlock_thread();
 
-	totblock--;
-	mem_in_use -= memh->len;
+	atomic_sub_u(&totblock, 1);
+	atomic_sub_z(&mem_in_use, memh->len);
 
 #ifdef DEBUG_MEMDUPLINAME
 	if (memh->need_free_name)
@@ -944,7 +936,7 @@
 #endif
 
 	if (memh->mmap) {
-		mmap_in_use -= memh->len;
+		atomic_sub_z(&mmap_in_use, memh->len);
 		if (munmap(memh, memh->len + sizeof(MemHead) + sizeof(MemTail)))
 			printf("Couldn't unmap memory %s\n", memh->name);
 	}

Modified: trunk/blender/source/blender/blenlib/BLI_threads.h
===================================================================
--- trunk/blender/source/blender/blenlib/BLI_threads.h	2013-08-19 10:44:18 UTC (rev 59280)
+++ trunk/blender/source/blender/blenlib/BLI_threads.h	2013-08-19 10:51:40 UTC (rev 59281)
@@ -50,6 +50,7 @@
 
 /*this is run once at startup*/
 void BLI_threadapi_init(void);
+void BLI_threadapi_exit(void);
 
 void    BLI_init_threads(struct ListBase *threadbase, void *(*do_thread)(void *), int tot);
 int     BLI_available_threads(struct ListBase *threadbase);

Modified: trunk/blender/source/blender/blenlib/intern/threads.c
===================================================================
--- trunk/blender/source/blender/blenlib/intern/threads.c	2013-08-19 10:44:18 UTC (rev 59280)
+++ trunk/blender/source/blender/blenlib/intern/threads.c	2013-08-19 10:51:40 UTC (rev 59281)
@@ -107,7 +107,7 @@
  *     BLI_end_threads(&lb);
  *
  ************************************************ */
-static pthread_mutex_t _malloc_lock = PTHREAD_MUTEX_INITIALIZER;
+static SpinLock _malloc_lock;
 static pthread_mutex_t _image_lock = PTHREAD_MUTEX_INITIALIZER;
 static pthread_mutex_t _image_draw_lock = PTHREAD_MUTEX_INITIALIZER;
 static pthread_mutex_t _viewer_lock = PTHREAD_MUTEX_INITIALIZER;
@@ -134,19 +134,26 @@
 
 static void BLI_lock_malloc_thread(void)
 {
-	pthread_mutex_lock(&_malloc_lock);
+	BLI_spin_lock(&_malloc_lock);
 }
 
 static void BLI_unlock_malloc_thread(void)
 {
-	pthread_mutex_unlock(&_malloc_lock);
+	BLI_spin_unlock(&_malloc_lock);
 }
 
 void BLI_threadapi_init(void)
 {
 	mainid = pthread_self();
+
+	BLI_spin_init(&_malloc_lock);
 }
 
+void BLI_threadapi_exit(void)
+{
+	BLI_spin_end(&_malloc_lock);
+}
+
 /* tot = 0 only initializes malloc mutex in a safe way (see sequence.c)
  * problem otherwise: scene render will kill of the mutex!
  */


Property changes on: trunk/blender/source/blender/editors/interface/interface.c
___________________________________________________________________
Modified: svn:mergeinfo

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list