Subject: Re: Malloc question
To: Tim Janes <janes@signal.dra.hmg.gb>
From: David Brownlee <abs@anim.dreamworks.com>
List: current-users
Date: 08/20/1997 09:58:16
You don't mention if you've checked the resource limits
(limit/unlimit from the command line, {get,set}rusage() from
C IIRC), but it not it could be the problem.
As to the efficiency of malloc() - NetBSD also ships with
gnumalloc, you could try linking with -lgnumalloc to see
if that improves matters.
David/abs
-- "Its hard to say it... I hate to say it... but its probably me..." --
On Wed, 20 Aug 1997, Tim Janes wrote:
>
> We have 2 sets of machines used for large memory intensive processing
> jobs. Alphas running Digital Unix 4.0B and PentiumPro 200 running
> NetBSD 1.2.1.
>
> All have 128Mbyte of phyiscal memory and 512Mbytes of swap.
>
> We have noticed that several programs that run OK on the Digital Unix but
> fail due to lack of memory on NetBSD.
>
> One of our researchers has noticed that the malloc routine on NetBSD
> appears have a large memory overhead. It is not yet clear if
> this is the cause of our problem but wondered if anyone could shed any
> light on the algorithm used by the malloc routine in this regard.
>
> I have appended his test program and comments.
>
> Many Thanks
>
> Tim.
>
>
> >From ponting Tue Aug 19 11:08:43 1997
> From: "Keith M. Ponting" <ponting>
> Received: from thomas.dra.hmg.gb (thomas.dra.hmg.gb [193.61.199.74])
> by byron.dra.hmg.gb (8.8.5/) with ESMTP id LAA11234;
> Tue, 19 Aug 1997 11:08:41 +0100 (BST)
> Return-Path: <ponting>
> Date: Tue, 19 Aug 1997 11:08:41 +0100 (BST)
> Message-Id: <LAA13461@thomas.dra.hmg.gb>
> To: janes
> Subject: memory holes on titan/NetBSD
> Status: RO
>
>
> Tim,
>
> The magic number for 100000 bytes requested seems to be 135168 =
> 0x21000. I would be interested in response from the newsgroup.
>
> Sundry other tests show the algorithm to be something like:
> up to 2044 bytes requested, use next highest power of 2
> more than 2044 bytes requested next highest ((power of 2+1)* 0x1000)
> Thus the allocation chains appear to be associated with chunks of
> sizes: 8 16 32 64 128 256 512 1024 2048 then a step to
> 0x2000=8192 0x3000=12288 0x5000=20480 etc.
>
> I am not quite sure I see the logic!
>
> Keith
>
> /***--------------------------------------------------------------------------
> * TITLE: memory.c
> * IDENT: $Id: memory.c,v 1.1 1997/08/19 09:51:27 ponting Exp $
> * AUTHOR: Dr.K.M.Ponting Defence Research Agency, Malvern
> * ENVIR: ANSI 'C'
> * USAGE: main program
> * TASKS: test memory allocator
> * (C) Crown Copyright $Date: 1997/08/19 09:51:27 $
> * DATES: <rcs change log automatically inserted here>
> * $Log: memory.c,v $
> * Revision 1.1 1997/08/19 09:51:27 ponting
> * Initial revision
> *
> --------------------------------------------------------------------------***/
>
> /********************************
> * include files *
> ********************************/
>
> #include <stdio.h> /* needed for printf function call */
> #include <stdlib.h> /* needed for EXIT_SUCCESS */
>
> /********************************
> * local constant declarations *
> ********************************/
>
>
> /********************************
> * local structure declarations *
> ********************************/
>
>
> /********************************
> * local function prototypes *
> ********************************/
>
>
> /********************************
> * local macro definitions *
> ********************************/
>
> /* gcc -Wall memory.c -lc -o memory */
>
> /************************************************************************
> * main program *
> ************************************************************************/
> int main(int argc,char **argv)
> {
> if ( argc < 2 )
> {
> printf("usage: %s memory_chunk_size [count=5]\n",argv[0]) ;
> }
> else
> {
> size_t chunk_size = strtoul(argv[1],NULL,0) ;
> int count = 5 ;
> int k ;
> char * old = NULL ;
> if ( argc > 2 )
> {
> count = strtol(argv[2],NULL,0) ;
> }
> for ( k = 0 ; k < count ; ++k )
> {
> char * base = (char*)malloc(chunk_size) ;
> if ( k > 0 ) /* meaningless on first allocation */
> {
> printf("size %lu base %p change 0x%lx=%ld overhead %ld\n",
> (unsigned long)chunk_size,
> base, (long)(base-old), (long)(base-old),
> (long)(base-old)-chunk_size) ;
> }
> old = base ;
> }
> }
> return(EXIT_SUCCESS);
> }
>
> /*-----------------------------------------------------------------------
> Output:
>
> 1) Compiled on NetBSD. I can believe the extra overhead 0x5000
> on one of the prints is due to memory grabbed by the printf statement.
> BUT why am I losing huge amounts of overhead space on the bigger
> allocations -- the worst case is allocating 135168 bytes which
> leaves a memory gap of 131072 bytes?
>
> gcc -Wall memory.c -lc -o memory
>
> titan8:~/astrec/tests% memory 100
> size 100 base 0x3080 change 0x80=128 overhead 28
> size 100 base 0x3100 change 0x80=128 overhead 28
> size 100 base 0x3180 change 0x80=128 overhead 28
> size 100 base 0x3200 change 0x80=128 overhead 28
> titan8:~/astrec/tests% memory 1000
> size 1000 base 0x3400 change 0x400=1024 overhead 24
> size 1000 base 0x3800 change 0x400=1024 overhead 24
> size 1000 base 0x3c00 change 0x400=1024 overhead 24
> size 1000 base 0x9000 change 0x5400=21504 overhead 20504
> titan8:~/astrec/tests% memory 10000
> size 10000 base 0x6000 change 0x3000=12288 overhead 2288
> size 10000 base 0xe000 change 0x8000=32768 overhead 22768
> size 10000 base 0x11000 change 0x3000=12288 overhead 2288
> size 10000 base 0x14000 change 0x3000=12288 overhead 2288
> titan8:~/astrec/tests% memory 100000
> size 100000 base 0x24000 change 0x21000=135168 overhead 35168
> size 100000 base 0x4a000 change 0x26000=155648 overhead 55648
> size 100000 base 0x6b000 change 0x21000=135168 overhead 35168
> size 100000 base 0x8c000 change 0x21000=135168 overhead 35168
> titan8:~/astrec/tests% memory 135164
> size 135164 base 0x24000 change 0x21000=135168 overhead 4
> size 135164 base 0x4a000 change 0x26000=155648 overhead 20484
> size 135164 base 0x6b000 change 0x21000=135168 overhead 4
> size 135164 base 0x8c000 change 0x21000=135168 overhead 4
> titan8:~/astrec/tests% memory 135168
> size 135168 base 0x44000 change 0x41000=266240 overhead 131072
> size 135168 base 0x8a000 change 0x46000=286720 overhead 151552
> size 135168 base 0xcb000 change 0x41000=266240 overhead 131072
> size 135168 base 0x10c000 change 0x41000=266240 overhead 131072
>
> 2) Compiled on alpha/osf1 -- the overhead ranges between 8 and
> 36 bytes, which seems much more sensible.
>
> gcc -Wall memory.c -lc -o memory
>
> thomas:astrec/tests% memory 100
> size 100 base 140000980 change 0x80=128 overhead 28
> size 100 base 140000a00 change 0x80=128 overhead 28
> size 100 base 140000a80 change 0x80=128 overhead 28
> size 100 base 140000b00 change 0x80=128 overhead 28
> thomas:astrec/tests% memory 1000
> size 1000 base 140002400 change 0x400=1024 overhead 24
> size 1000 base 140002800 change 0x400=1024 overhead 24
> size 1000 base 140002c00 change 0x400=1024 overhead 24
> size 1000 base 140003000 change 0x400=1024 overhead 24
> thomas:astrec/tests% memory 10000
> size 10000 base 140004720 change 0x2720=10016 overhead 16
> size 10000 base 140006e40 change 0x2720=10016 overhead 16
> size 10000 base 140009560 change 0x2720=10016 overhead 16
> size 10000 base 14000bc80 change 0x2720=10016 overhead 16
> thomas:astrec/tests% memory 100000
> size 100000 base 14001a6c0 change 0x186c0=100032 overhead 32
> size 100000 base 140032d80 change 0x186c0=100032 overhead 32
> size 100000 base 14004b440 change 0x186c0=100032 overhead 32
> size 100000 base 140063b00 change 0x186c0=100032 overhead 32
> thomas:astrec/tests% memory 135160
> size 135160 base 140023000 change 0x21000=135168 overhead 8
> size 135160 base 140044000 change 0x21000=135168 overhead 8
> size 135160 base 140065000 change 0x21000=135168 overhead 8
> size 135160 base 140086000 change 0x21000=135168 overhead 8
> thomas:astrec/tests% memory 135164
> size 135164 base 140023020 change 0x21020=135200 overhead 36
> size 135164 base 140044040 change 0x21020=135200 overhead 36
> size 135164 base 140065060 change 0x21020=135200 overhead 36
> size 135164 base 140086080 change 0x21020=135200 overhead 36
> thomas:astrec/tests% memory 135168
> size 135168 base 140023020 change 0x21020=135200 overhead 32
> size 135168 base 140044040 change 0x21020=135200 overhead 32
> size 135168 base 140065060 change 0x21020=135200 overhead 32
> size 135168 base 140086080 change 0x21020=135200 overhead 32
>
> */
>