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.
This commit is contained in:
@@ -107,6 +107,9 @@ extern "C" {
|
|||||||
* blocks. */
|
* blocks. */
|
||||||
void MEM_printmemlist(void);
|
void MEM_printmemlist(void);
|
||||||
|
|
||||||
|
/** Print statistics about memory usage */
|
||||||
|
void MEM_printmemlist_stats(void);
|
||||||
|
|
||||||
/** Set the callback function for error output. */
|
/** Set the callback function for error output. */
|
||||||
void MEM_set_error_callback(void (*func)(char *));
|
void MEM_set_error_callback(void (*func)(char *));
|
||||||
|
|
||||||
|
@@ -332,6 +332,91 @@ void *MEM_mapallocN(unsigned int len, const char *str)
|
|||||||
#endif
|
#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; a<totpb; a++) {
|
||||||
|
if(a == b) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if(strcmp(printblock[a].name, printblock[b].name) == 0) {
|
||||||
|
printblock[b].len += printblock[a].len;
|
||||||
|
printblock[b].items++;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
b++;
|
||||||
|
memcpy(&printblock[b], &printblock[a], sizeof(MemPrintBlock));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
totpb= b+1;
|
||||||
|
|
||||||
|
/* sort by length and print */
|
||||||
|
qsort(printblock, totpb, sizeof(MemPrintBlock), compare_len);
|
||||||
|
printf("\ntotal memory len: %.3f MB\n", (double)mem_in_use/(double)(1024*1024));
|
||||||
|
for(a=0, pb=printblock; a<totpb; a++, pb++)
|
||||||
|
printf("%s items: %d, len: %.3f MB\n", pb->name, pb->items, (double)pb->len/(double)(1024*1024));
|
||||||
|
|
||||||
|
free(printblock);
|
||||||
|
|
||||||
|
mem_unlock_thread();
|
||||||
|
}
|
||||||
|
|
||||||
/* Prints in python syntax for easy */
|
/* Prints in python syntax for easy */
|
||||||
static void MEM_printmemlist_internal( int pydict )
|
static void MEM_printmemlist_internal( int pydict )
|
||||||
|
@@ -148,6 +148,9 @@ void BKE_image_all_free_anim_ibufs(int except_frame);
|
|||||||
|
|
||||||
void BKE_image_memorypack(struct Image *ima);
|
void BKE_image_memorypack(struct Image *ima);
|
||||||
|
|
||||||
|
/* prints memory statistics for images */
|
||||||
|
void BKE_image_print_memlist(void);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@@ -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; level<IB_MIPMAP_LEVELS; level++) {
|
||||||
|
ibufm= ibuf->mipmap[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)
|
void BKE_image_free_all_textures(void)
|
||||||
{
|
{
|
||||||
Tex *tex;
|
Tex *tex;
|
||||||
|
@@ -4130,6 +4130,14 @@ void RE_Database_Free(Render *re)
|
|||||||
Object *ob = NULL;
|
Object *ob = NULL;
|
||||||
LampRen *lar;
|
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 */
|
/* FREE */
|
||||||
|
|
||||||
for(lar= re->lampren.first; lar; lar= lar->next) {
|
for(lar= re->lampren.first; lar; lar= lar->next) {
|
||||||
|
Reference in New Issue
Block a user