From baf7be9e466a2f111b030b9098be71f3aba3aca7 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Fri, 1 Feb 2008 12:14:15 +0000 Subject: [PATCH] Memory usage debugging: now with the -d debug option enabled, at the end of rendering it prints memory usage for images and all memory blocks. --- intern/guardedalloc/MEM_guardedalloc.h | 3 + intern/guardedalloc/intern/mallocn.c | 85 +++++++++++++++++++ source/blender/blenkernel/BKE_image.h | 3 + source/blender/blenkernel/intern/image.c | 41 +++++++++ .../render/intern/source/convertblender.c | 8 ++ 5 files changed, 140 insertions(+) diff --git a/intern/guardedalloc/MEM_guardedalloc.h b/intern/guardedalloc/MEM_guardedalloc.h index 94276c0454a..73eddff7d8a 100644 --- a/intern/guardedalloc/MEM_guardedalloc.h +++ b/intern/guardedalloc/MEM_guardedalloc.h @@ -106,6 +106,9 @@ extern "C" { /** Print a list of the names and sizes of all allocated memory * blocks. */ void MEM_printmemlist(void); + + /** Print statistics about memory usage */ + void MEM_printmemlist_stats(void); /** Set the callback function for error output. */ void MEM_set_error_callback(void (*func)(char *)); diff --git a/intern/guardedalloc/intern/mallocn.c b/intern/guardedalloc/intern/mallocn.c index 413f4d80514..c1ddfa71a10 100644 --- a/intern/guardedalloc/intern/mallocn.c +++ b/intern/guardedalloc/intern/mallocn.c @@ -332,6 +332,91 @@ void *MEM_mapallocN(unsigned int len, const char *str) #endif } +/* Memory statistics print */ +typedef struct MemPrintBlock { + const char *name; + unsigned long len; + int items; +} MemPrintBlock; + +static int compare_name(const void *p1, const void *p2) +{ + const MemPrintBlock *pb1= (const MemPrintBlock*)p1; + const MemPrintBlock *pb2= (const MemPrintBlock*)p2; + + return strcmp(pb1->name, pb2->name); +} + +static int compare_len(const void *p1, const void *p2) +{ + const MemPrintBlock *pb1= (const MemPrintBlock*)p1; + const MemPrintBlock *pb2= (const MemPrintBlock*)p2; + + if(pb1->len < pb2->len) + return 1; + else if(pb1->len == pb2->len) + return 0; + else + return -1; +} + +void MEM_printmemlist_stats() +{ + MemHead *membl; + MemPrintBlock *pb, *printblock; + int totpb, a, b; + + mem_lock_thread(); + + /* put memory blocks into array */ + printblock= malloc(sizeof(MemPrintBlock)*totblock); + + pb= printblock; + totpb= 0; + + membl = membase->first; + if (membl) membl = MEMNEXT(membl); + + while(membl) { + pb->name= membl->name; + pb->len= membl->len; + pb->items= 1; + + totpb++; + pb++; + + if(membl->next) + membl= MEMNEXT(membl->next); + else break; + } + + /* sort by name and add together blocks with the same name */ + qsort(printblock, totpb, sizeof(MemPrintBlock), compare_name); + for(a=0, b=0; aname, pb->items, (double)pb->len/(double)(1024*1024)); + + free(printblock); + + mem_unlock_thread(); +} /* Prints in python syntax for easy */ static void MEM_printmemlist_internal( int pydict ) diff --git a/source/blender/blenkernel/BKE_image.h b/source/blender/blenkernel/BKE_image.h index ca34240cf27..a584722031b 100644 --- a/source/blender/blenkernel/BKE_image.h +++ b/source/blender/blenkernel/BKE_image.h @@ -148,6 +148,9 @@ void BKE_image_all_free_anim_ibufs(int except_frame); void BKE_image_memorypack(struct Image *ima); +/* prints memory statistics for images */ +void BKE_image_print_memlist(void); + #ifdef __cplusplus } #endif diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c index 0c45356eb0b..3b7ab4951f6 100644 --- a/source/blender/blenkernel/intern/image.c +++ b/source/blender/blenkernel/intern/image.c @@ -629,6 +629,47 @@ void free_old_images() } } +static unsigned long image_mem_size(Image *ima) +{ + ImBuf *ibuf, *ibufm; + int level; + unsigned long size = 0; + + size= 0; + for(ibuf= ima->ibufs.first; ibuf; ibuf= ibuf->next) { + if(ibuf->rect) size += MEM_allocN_len(ibuf->rect); + else if(ibuf->rect_float) size += MEM_allocN_len(ibuf->rect_float); + + for(level=0; levelmipmap[level]; + if(ibufm) { + if(ibufm->rect) size += MEM_allocN_len(ibufm->rect); + else if(ibufm->rect_float) size += MEM_allocN_len(ibufm->rect_float); + } + } + } + + return size; +} + +void BKE_image_print_memlist(void) +{ + Image *ima; + unsigned long size, totsize= 0; + + for(ima= G.main->image.first; ima; ima= ima->id.next) + totsize += image_mem_size(ima); + + printf("\ntotal image memory len: %.3lf MB\n", (double)totsize/(double)(1024*1024)); + + for(ima= G.main->image.first; ima; ima= ima->id.next) { + size= image_mem_size(ima); + + if(size) + printf("%s len: %.3f MB\n", ima->id.name+2, (double)size/(double)(1024*1024)); + } +} + void BKE_image_free_all_textures(void) { Tex *tex; diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c index 38ae7fde181..e4c62c15034 100644 --- a/source/blender/render/intern/source/convertblender.c +++ b/source/blender/render/intern/source/convertblender.c @@ -4129,6 +4129,14 @@ void RE_Database_Free(Render *re) { Object *ob = NULL; LampRen *lar; + + /* statistics for debugging render memory usage */ + if(G.f & G_DEBUG) { + if((re->r.scemode & R_PREVIEWBUTS)==0) { + BKE_image_print_memlist(); + MEM_printmemlist_stats(); + } + } /* FREE */