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]
Other format: [Raw text]

[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

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