develooper Front page | perl.perl5.porters | Postings from September 2014

Re: sv_grow() and malloc()

Thread Previous | Thread Next
From:
H.Merijn Brand
Date:
September 23, 2014 13:03
Subject:
Re: sv_grow() and malloc()
Message ID:
20140923150327.71a8d1de@pc09.procura.nl
On Tue, 23 Sep 2014 12:49:56 +0100, Dave Mitchell <davem@iabyn.com>
wrote:

> (this is spin-off from Reini's suggested work to tweak sv_grow()
> allocations).
> 
> I've been thinking about about all our heuristics for growing (and
> over-growing) strings in sv_grow(), and how it's likely to interact with
> the OS's malloc() library.
> 
> It occurred to me that malloc() libraries are likely to have some
> reasonably sane and predictable behaviour (ha ha, I know, I know...).
> For example, since malloc() guarantees alignment for any kind of variable,
> its likely to allocate blocks of at least 4/8 bytes on 32/64-bit systems;
> it's therefore probably not efficient to malloc PVX's of less than 4/8
> bytes (we'll just waste time later calling realloc() which just returns
> the same address).
> 
> Similarly, the malloc may in fact over-allocate, and in fact some quick
> tests with the malloc on my 64-bit linux system implies that it initially
> allocates 24 bytes, even for a malloc(1).
> 
> My two main thoughts are (a) there are probably people on this list
> who know much more about malloc behaviours than me, especially on obscure
> platforms - so I'd welcome any input.
> 
> Second, it occurs to me that we could probably do some run-time probing
> of the malloc() library to determine optimum initial malloc() and then
> realloc() sizes.
> 
> For example the following simple C code:
> 
>     #include <stdio.h>
>     #include <malloc.h>
> 
>     int main(int argc, char**argv)
>     {
>         int i;
>         void *q, *p = malloc(1);
>         malloc(1); /* poison reallocs */
>         for (i=1; i<130; i++) {
>             q = realloc(p,i);
>             if (p != q) {
>                 printf("after %3d bytes realloc() using different address\n", i-1);
>                 malloc(i); /* poison reallocs */
>             }
>             p=q;
>         }
>     }
> 
> gives this output on my system:
> 
>     after  24 bytes realloc() using different address
>     after  40 bytes realloc() using different address
>     after  56 bytes realloc() using different address
>     after  72 bytes realloc() using different address
>     after  88 bytes realloc() using different address
>     after 104 bytes realloc() using different address
>     after 120 bytes realloc() using different address

HP-UX 10.20 PA-RISC (pa20),  HP C-ANSI-C
32bit:
after   8 bytes realloc () using different address
after  16 bytes realloc () using different address
after  24 bytes realloc () using different address
after  32 bytes realloc () using different address
after  40 bytes realloc () using different address
after  48 bytes realloc () using different address
after  56 bytes realloc () using different address
after  64 bytes realloc () using different address
after  72 bytes realloc () using different address
after  80 bytes realloc () using different address
after  88 bytes realloc () using different address
after  96 bytes realloc () using different address
after 104 bytes realloc () using different address
after 112 bytes realloc () using different address
after 120 bytes realloc () using different address
after 128 bytes realloc () using different address

HP-UX 11.00 PA-RISC (pa20w), HP C-ANSI-C
64bit:
after   8 bytes realloc () using different address
after  16 bytes realloc () using different address
after  24 bytes realloc () using different address
after  32 bytes realloc () using different address
after  40 bytes realloc () using different address
after  48 bytes realloc () using different address
after  56 bytes realloc () using different address
after  64 bytes realloc () using different address
after  72 bytes realloc () using different address
after  80 bytes realloc () using different address
after  88 bytes realloc () using different address
after  96 bytes realloc () using different address
after 104 bytes realloc () using different address
after 112 bytes realloc () using different address
after 120 bytes realloc () using different address
after 128 bytes realloc () using different address

32bit:
after   8 bytes realloc () using different address
after  16 bytes realloc () using different address
after  24 bytes realloc () using different address
after  32 bytes realloc () using different address
after  40 bytes realloc () using different address
after  48 bytes realloc () using different address
after  56 bytes realloc () using different address
after  64 bytes realloc () using different address
after  72 bytes realloc () using different address
after  80 bytes realloc () using different address
after  88 bytes realloc () using different address
after  96 bytes realloc () using different address
after 104 bytes realloc () using different address
after 112 bytes realloc () using different address
after 120 bytes realloc () using different address
after 128 bytes realloc () using different address

HP-UX 11.31 Itanium (ia64), HP C-ANSI-C
64bit:
after  16 bytes realloc () using different address
after  32 bytes realloc () using different address
after  48 bytes realloc () using different address
after  64 bytes realloc () using different address
after  80 bytes realloc () using different address
after  96 bytes realloc () using different address
after 112 bytes realloc () using different address
after 128 bytes realloc () using different address

32bit:
after  16 bytes realloc () using different address
after  32 bytes realloc () using different address
after  48 bytes realloc () using different address
after  64 bytes realloc () using different address
after  80 bytes realloc () using different address
after  96 bytes realloc () using different address
after 112 bytes realloc () using different address
after 128 bytes realloc () using different address

AIX 5.3.0.0 Power5, xlc
64bit:
after  16 bytes realloc () using different address
after  48 bytes realloc () using different address
after  80 bytes realloc () using different address
after 112 bytes realloc () using different address

32bit:
after   8 bytes realloc () using different address
after  24 bytes realloc () using different address
after  40 bytes realloc () using different address
after  56 bytes realloc () using different address
after  72 bytes realloc () using different address
after  88 bytes realloc () using different address
after 104 bytes realloc () using different address
after 120 bytes realloc () using different address


Linux:
$ cc -O -o ax allocinf.c
$ ./ax
Exit 16

> which implies the malloc() library initially allocates 24 bytes, then
> reallocs in 16 byte increments. A simple probe like the above at startup
> time might reveal the optimum size to initially size strings, and what
> factor to round up by when reallocing.
> 
> I haven't researched this properly yet (I'm secretly hoping I wont have to
> and someone already knows the answers).

-- 
H.Merijn Brand  http://tux.nl   Perl Monger  http://amsterdam.pm.org/
using perl5.00307 .. 5.19   porting perl5 on HP-UX, AIX, and openSUSE
http://mirrors.develooper.com/hpux/        http://www.test-smoke.org/
http://qa.perl.org   http://www.goldmark.org/jeff/stupid-disclaimers/

Thread Previous | Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About