Good numbers from Ritter's new string allocator
Stefan Olsson
stefan@noname4us.com
Tue Nov 13 06:05:00 GMT 2001
Hi!
We have not concluded our testing yet, but we basically get the same improvements.
Currently experimenting with "rounding" the _capacity even for strings _shorter_ than 128
bytes which should decrease memory fragmentation even further (This is of high importance
to us since the application _will/must_ run for long periods of time).
Since we are using the pthread_alloc allocator in some parts of the application we are
looking at some "modifications" to this as well, but as I said - I will get back with some
more actual numbers and ideas...
Take care everyone!
/Stefan
Paolo Carlini wrote:
> Hi,
>
> today I have begun benchmarking on my PII-400 (Linux.2.4.10, glibc2.2.4) Loren James
> Rittle's proposal for an improved basic_string memory allocation:
>
> http://gcc.gnu.org/ml/libstdc++/2001-07/msg00084.html
>
> The first numbers are from Stefan's test, for 100000 concatenations:
>
> /////////
> #include <string>
>
> #define SIZE 100000
>
> using namespace std;
>
> int main()
> {
> string s;
> int i;
>
> for( i=0; i<SIZE; i++ )
> {
> s+="a";
> }
> }
> /////////
>
> ... and are really ***astounding*** (5 consecutive runs):
>
> gcc version 3.1 20011122 (experimental)
> ---------------------------------------
> 18.470u 2.880s 0:21.83 97.8% 0+0k 0+0io 163pf+0w
> 19.230u 2.750s 0:22.49 97.7% 0+0k 0+0io 163pf+0w
> 18.480u 3.000s 0:21.83 98.3% 0+0k 0+0io 163pf+0w
> 18.790u 3.010s 0:22.14 98.4% 0+0k 0+0io 163pf+0w
> 19.540u 2.600s 0:22.52 98.3% 0+0k 0+0io 163pf+0w
>
> gcc version 3.1 20011122 (experimental) + Loren's patch
> (__malloc_header_size == 8)
> -------------------------------------------------------
> 0.110u 0.000s 0:00.11 100.0% 0+0k 0+0io 162pf+0w
> 0.110u 0.010s 0:00.11 109.0% 0+0k 0+0io 162pf+0w
> 0.120u 0.000s 0:00.11 109.0% 0+0k 0+0io 162pf+0w
> 0.100u 0.020s 0:00.11 109.0% 0+0k 0+0io 162pf+0w
> 0.110u 0.000s 0:00.11 100.0% 0+0k 0+0io 162pf+0w
>
> For 1000000 of concatenations (out of cache) the difference is not less impressive, with
> unpatched gcc beyond 600 seconds and patched gcc:
>
> 1.350u 0.640s 0:02.01 99.0% 0+0k 0+0io 163pf+0w
> 1.290u 0.670s 0:02.01 97.5% 0+0k 0+0io 163pf+0w
> 1.430u 0.570s 0:02.02 99.0% 0+0k 0+0io 163pf+0w
> 1.380u 0.590s 0:02.02 97.5% 0+0k 0+0io 163pf+0w
> 1.260u 0.730s 0:02.02 98.5% 0+0k 0+0io 163pf+0w
>
> The following are the values of the capacity() corresponding to a given value x in
> reserve(x):
>
> x capacity()
> --------------------------
> 32 32
> 64 64
> 128 235
> 256 491
> 512 747
> 1024 1259
> 2048 2283
> 4096 8171
> 8192 12267
> 16384 20459
> 32768 36843
> 65536 69611
> 131072 135147
> 262144 266219
>
> In my opionion they are absolutely reasonable, considering that it always possible to
> shrink to fit the capacity to size() with a reserve() call (now it always works ;-)
>
> So, the results are absolutely promising and I'm planning to carry out more tests for
> different (more realistic?) benchmarks, soon on P4 too.
>
> Eventually, it should also be assessed if an appropriate configure test for
> __malloc_header_size is really worthy. I understand from Ulrich Drepper's message:
>
> http://gcc.gnu.org/ml/libstdc++/2001-07/msg00077.html
>
> that perhaps we can go with an hardwired 4*sizeof(void*). Otherwise we have to implement
> an aoutconf test which Loren has already outlined:
>
> http://gcc.gnu.org/ml/libstdc++/2001-07/msg00083.html
>
> I'm attaching to this message a freshly made diff (vs current mainline) of Rittle's
> proposal which you all may apply to carry out your own experiments (it has
> __malloc_header_size == 8 == 2*sizeof(void*), the optimal value for my Linux, it should
> also be ok for FreeBSD and Solaris)
>
> Please, post your results and opinions!!
>
> Cheers,
> Paolo.
>
> *** basic_string.tcc.orig Thu Nov 22 18:59:57 2001
> --- basic_string.tcc Thu Nov 22 18:59:35 2001
> *************** namespace std
> *** 374,379 ****
> --- 374,398 ----
> // terminating null char_type() element, plus enough for the
> // _Rep data structure. Whew. Seemingly so needy, yet so elemental.
> size_t __size = (__capacity + 1) * sizeof(_CharT) + sizeof(_Rep);
> +
> + const size_t __pagesize = 4096; // This magic constant, from OS.
> + const size_t __malloc_header_size = 8; // This one, from malloc.
> + if ((__size + __malloc_header_size) > __pagesize)
> + {
> + size_t __extra =
> + (__pagesize - ((__size + __malloc_header_size) % __pagesize))
> + % __pagesize;
> + __capacity += __extra / sizeof(_CharT);
> + __size = (__capacity + 1) * sizeof(_CharT) + sizeof(_Rep);
> + }
> + else if (__size > 128) // This magic constant is from stl_alloc.h.
> + {
> + size_t __extra =
> + (256 - ((__size + __malloc_header_size) % 256)) % 256;
> + __capacity += __extra / sizeof(_CharT);
> + __size = (__capacity + 1) * sizeof(_CharT) + sizeof(_Rep);
> + }
> +
> // NB: Might throw, but no worries about a leak, mate: _Rep()
> // does not throw.
> void* __place = _Raw_bytes_alloc(__alloc).allocate(__size);
--
Military intelligence is a contradiction in terms.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://gcc.gnu.org/pipermail/libstdc++/attachments/20011113/78443d81/attachment.htm>
More information about the Libstdc++
mailing list