monotone-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: HOWTO: benchmarking monotone (was Re: [Monotone-devel] "memory exhau


From: Eric Anderson
Subject: Re: HOWTO: benchmarking monotone (was Re: [Monotone-devel] "memory exhausted" error for 'mtn list status' command)
Date: Sat, 29 Jul 2006 15:52:19 -0700

To follow up on my previous discussion, there is a fairly substantial
difference between memtime and massif for some programs.  Consider the
attached foo.cc program.  All it does is allocate and de-allocate
memory.  There is one line marked with "the magic line separating
memtime from massif".  massif doesn't care if that line is 0 or 1, it
will report essentially the same graph in either case.  Conversely,
memtime cares considerably about that line.  I updated memtime to
print out interim statistics
(d5b37aa3d431495bc661da56e6bdb2233fdd32be).  With the free disabled,
memory usage is pretty much constant at around 74MB for the entire
run; with the free enabled, memory usage (size and resident) goes up
and down across the run.

The difference is that valgrind is size(allocated_bytes -
freed_bytes), whereas memtime is looking at (allocated_bytes -
freed_bytes + external_fragmentation).  It is the external
fragmentation caused by the allocation of a little memory after
allocating a large amount that means that even if the large amount is
freed, since the little memory is allocated after it, the resident
size doesn't drop.

You could ask which one is right, and I would argue both are right,
they are just measuring different things.
        -Eric

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/time.h>
#include <time.h>

struct foo {
    struct foo *next;
};

foo *
alloc_chain_reverse(int nelems, int elem_size)
{
    foo *ret = NULL;
    for(int i=0;i<nelems;++i) {
        foo *n = (foo *)malloc(elem_size);
        memset((void *)n,'\0',elem_size);
        n->next = ret;
        ret = n;
    }
    return ret;
}

foo *
free_chain(foo *chain)
{
    while(chain != NULL) {
        foo *n = chain->next;
        free(chain);
        chain = n;
    }
    return chain;
}

double dbltime()
{
    struct timeval tv;
    gettimeofday(&tv,NULL);
    return tv.tv_sec + tv.tv_usec * 1e-6;
}

void wait(double seconds)
{
    double end = dbltime() + seconds;
    while(dbltime() < end) {
    }
}


int main()
{
    {
        foo *chain1 = alloc_chain_reverse(1000000,64);
        wait(0.25);
        foo *chain2 = alloc_chain_reverse(1,32);
        wait(0.25);
        chain1 = free_chain(chain1);
        wait(0.25);
        if (0) { // the magic line separating memtime from massif
            free_chain(chain2);
        }
    }

    for(int i=0;i<3;++i) {
        foo *chain1 = alloc_chain_reverse(20000,400);
        wait(0.25);
        free_chain(chain1);
        wait(0.25);
    }

    return 0;
}


reply via email to

[Prev in Thread] Current Thread [Next in Thread]