This is the mail archive of the
libstdc++@gcc.gnu.org
mailing list for the libstdc++ project.
[Patch] mt_alloc: tunable alignment
- From: Paolo Carlini <pcarlini at suse dot de>
- To: libstdc++ <libstdc++ at gcc dot gnu dot org>
- Cc: Benjamin Kosnik <bkoz at redhat dot com>
- Date: Fri, 18 Jun 2004 23:25:13 +0200
- Subject: [Patch] mt_alloc: tunable alignment
Hi all, hi Benjamin,
the below is the promised patch: it adds an additional tunable alignment
parameter. As is, the alignment on 32 bit machines ends up being 8 (the
same value guaranteed by malloc). On x86, for some testcases in the
performance testsuite we pay an additional memory overhead around 10%,
we can perhaps work on improving it later. Anyway, this is only the
default of an additional degree of freedom.
Tested check/check-performance on x86/x86-64/ia64. Also checked of course
that no wrong alignment warnings are emitted on ia64 at run time.
Ok with you?
Paolo.
//////////////////
2004-06-18 Paolo Carlini <pcarlini@suse.de>
* include/ext/mt_allocator (__mt_alloc<>::_Tune): Add _M_align,
the alignment requested.
(__mt_alloc<>::_Tune::_Tune): Tweak consistently.
(__mt_alloc<>::allocate): Use it instead of sizeof(_Block_record).
(__mt_alloc<>::allocate): Likewise.
diff -urN libstdc++-v3-orig/include/ext/mt_allocator.h libstdc++-v3/include/ext/mt_allocator.h
--- libstdc++-v3-orig/include/ext/mt_allocator.h 2004-05-18 17:58:33.000000000 +0200
+++ libstdc++-v3/include/ext/mt_allocator.h 2004-06-18 21:47:36.000000000 +0200
@@ -118,12 +118,18 @@
// assigned and explained in detail below.
struct _Tune
{
+ // Alignment needed.
+ // NB: In any case must be >= sizeof(_Block_record), that
+ // is 4 on 32 bit machines and 8 on 64 bit machines.
+ size_t _M_align;
+
// Allocation requests (after round-up to power of 2) below
// this value will be handled by the allocator. A raw new/
// call will be used for requests larger than this value.
size_t _M_max_bytes;
- // Size in bytes of the smallest bin (must be a power of 2).
+ // Size in bytes of the smallest bin.
+ // NB: Must be a power of 2 and >= _M_align.
size_t _M_min_bin;
// In order to avoid fragmenting and minimize the number of
@@ -150,18 +156,19 @@
explicit
_Tune()
- : _M_max_bytes(128), _M_min_bin(8),
+ : _M_align(8), _M_max_bytes(128), _M_min_bin(8),
_M_chunk_size(4096 - 4 * sizeof(void*)),
_M_max_threads(4096), _M_freelist_headroom(10),
_M_force_new(getenv("GLIBCXX_FORCE_NEW") ? true : false)
{ }
explicit
- _Tune(size_t __maxb, size_t __minbin, size_t __chunk,
- size_t __maxthreads, size_t __headroom, bool __force)
- : _M_max_bytes(__maxb), _M_min_bin(__minbin), _M_chunk_size(__chunk),
- _M_max_threads(__maxthreads), _M_freelist_headroom(__headroom),
- _M_force_new(__force)
+ _Tune(size_t __align, size_t __maxb, size_t __minbin,
+ size_t __chunk, size_t __maxthreads, size_t __headroom,
+ bool __force)
+ : _M_align(__align), _M_max_bytes(__maxb), _M_min_bin(__minbin),
+ _M_chunk_size(__chunk), _M_max_threads(__maxthreads),
+ _M_freelist_headroom(__headroom), _M_force_new(__force)
{ }
};
@@ -306,8 +313,10 @@
_Block_record* __block = NULL;
if (__bin._M_first[__thread_id] == NULL)
{
+ // NB: For alignment reasons, we can't use the first _M_align
+ // bytes, even when sizeof(_Block_record) < _M_align.
const size_t __bin_size = ((_S_options._M_min_bin << __which)
- + sizeof(_Block_record));
+ + _S_options._M_align);
size_t __block_count = _S_options._M_chunk_size / __bin_size;
// Are we using threads?
@@ -399,7 +408,7 @@
}
#endif
- char* __c = reinterpret_cast<char*>(__block) + sizeof(_Block_record);
+ char* __c = reinterpret_cast<char*>(__block) + _S_options._M_align;
return static_cast<_Tp*>(static_cast<void*>(__c));
}
@@ -421,7 +430,7 @@
const size_t __which = _S_binmap[__bytes];
const _Bin_record& __bin = _S_bin[__which];
- char* __c = reinterpret_cast<char*>(__p) - sizeof(_Block_record);
+ char* __c = reinterpret_cast<char*>(__p) - _S_options._M_align;
_Block_record* __block = reinterpret_cast<_Block_record*>(__c);
#ifdef __GTHREADS