This is the mail archive of the libstdc++@gcc.gnu.org mailing list for the libstdc++ project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: [Fwd: basic_string<> - useless because of its poor performance]


In article <m3wv5n10g5.fsf@otr.mynet>,
Ulrich Drepper <drepper@redhat.com> writes:

>> First of all, since the C++ library is allocating memory for strings
>> using the standard malloc() interface, it should consider always
>> starting and growing the allocation by pagesize instead of 1 after
>> it may no longer use the fast allocator.

> Wrong.  Allocating pagesize bytes causes enormous fragmentation

[under some malloc implementations] [...]

OK, excellent observation for anyone that actually wants to translate
my original observation into a working patch (I now have a somewhat
system-dependent version working well in my tree that I will attempt
to generalize over time).  I do fully agree that some libc
implementations maintain data structures within/before/after the
memory regions that they give to user programs.  However, for the
record, some do not since their implementors noticed interesting
paging behavior on modern hardware platforms while malloc(), free(),
etc. walked these scattered administrative pointers...

BTW, for decent performance (before going to an exponential request
size rounding policy), would you agree that the general formula is:

M*pagesize-N*sizeof(void*)

where N is the per-system tunable parameter (0, 2 and 4 seen in
practice) and M is the smallest whole number selectable which makes
the quantity greater than or equal to the higher-layer requested
capacity.

Assuming that autoconf already found (for the target):

ac_cv_header_stdlib_h='yes'
ac_cv_header_unistd_h='yes'
ac_cv_func_getpagesize='yes'

is this test basically OK (I understand how to repackage the test in
the form of those tests in e.g. libstdc++-v3/acinclude.m4 and gcc/aclocal.m4)?

#include <stdlib.h>
#include <unistd.h>

int main ()
{
  int i = getpagesize ();
  void* p1 = malloc (i);
  void* p2 = malloc (i);
  void* p3 = malloc (i);
  void* p4 = malloc (i*2);
  void* p5 = malloc (i*2);
  void* p6 = malloc (i*2);
  int n = abs (p2 - p1) - i;
  int d1 = abs (p3 - p2) == abs (p2 - p1);
  int d2 = abs (p6 - p5) == abs (p5 - p4);
  int d3 = (abs (p6 - p5) - i) == abs (p2 - p1);

  if ((n <= sizeof(void*)*4) && d1 && d2 && d3)
    printf ("%d == N*sizeof(void)\n", n);
  else
    printf ("strange malloc implementation, please teach me\n");

  return 0;
}

Example detections:

Solaris 2.7: 8 == N*sizeof(void) [i.e. N=2]
Digital UNIX V4.0A: 32 == N*sizeof(void*) [i.e. N=4]
Red Hat 6.1: 8 == N*sizeof(void) [i.e. N=2]
FreeBSD 4.2: 0 == N*sizeof(void)

Regards,
Loren


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]