public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [v3] __mt_alloc tweaks
@ 2004-10-17 16:03 Benjamin Kosnik
  0 siblings, 0 replies; 2+ messages in thread
From: Benjamin Kosnik @ 2004-10-17 16:03 UTC (permalink / raw)
  To: gcc-patches; +Cc: libstdc++

[-- Attachment #1: Type: text/plain, Size: 66 bytes --]


Small simplifications and performance tweaks.

tested x86/linux


[-- Attachment #2: p.20041017 --]
[-- Type: text/plain, Size: 12748 bytes --]

2004-10-17  Benjamin Kosnik  <bkoz@redhat.com>

	* include/ext/mt_allocator.h (__pool::_M_get_align): New.
	(__mt_alloc::allocate): Use it.
	* src/mt_allocator.cc (__pool::_M_reclaim_block): Use it.
	(__pool::_M_reserve_block): Simplify block allocation.

Index: include/ext/mt_allocator.h
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/include/ext/mt_allocator.h,v
retrieving revision 1.39
diff -c -p -r1.39 mt_allocator.h
*** include/ext/mt_allocator.h	14 Oct 2004 23:03:23 -0000	1.39
--- include/ext/mt_allocator.h	17 Oct 2004 15:13:31 -0000
*************** namespace __gnu_cxx
*** 169,174 ****
--- 169,178 ----
      _M_get_binmap(size_t __bytes)
      { return _M_binmap[__bytes]; }
  
+     const size_t
+     _M_get_align()
+     { return _M_options._M_align; }
+ 
      explicit __pool_base() 
      : _M_options(_Tune()), _M_binmap(NULL), _M_init(false) { }
  
*************** namespace __gnu_cxx
*** 708,715 ****
  	  __bin._M_first[__thread_id] = __block->_M_next;
  	  
  	  __pool._M_adjust_freelist(__bin, __block, __thread_id);
! 	  const __pool_base::_Tune& __options = __pool._M_get_options();
! 	  __c = reinterpret_cast<char*>(__block) + __options._M_align;
  	}
        else
  	{
--- 712,718 ----
  	  __bin._M_first[__thread_id] = __block->_M_next;
  	  
  	  __pool._M_adjust_freelist(__bin, __block, __thread_id);
! 	  __c = reinterpret_cast<char*>(__block) + __pool._M_get_align();
  	}
        else
  	{
Index: src/mt_allocator.cc
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/src/mt_allocator.cc,v
retrieving revision 1.7
diff -c -p -r1.7 mt_allocator.cc
*** src/mt_allocator.cc	15 Oct 2004 10:54:56 -0000	1.7
--- src/mt_allocator.cc	17 Oct 2004 15:13:31 -0000
*************** namespace __gnu_cxx
*** 58,64 ****
  	      {
  		_Block_address* __tmp = __bin._M_address->_M_next;
  		::operator delete(__bin._M_address->_M_initial);
- 		delete __bin._M_address;
  		__bin._M_address = __tmp;
  	      }
  	    ::operator delete(__bin._M_first);
--- 58,63 ----
*************** namespace __gnu_cxx
*** 75,82 ****
      const size_t __which = _M_binmap[__bytes];
      _Bin_record& __bin = _M_bin[__which];
  
!     const _Tune& __options = _M_get_options();
!     char* __c = __p - __options._M_align;
      _Block_record* __block = reinterpret_cast<_Block_record*>(__c);
        
      // Single threaded application - return to global pool.
--- 74,80 ----
      const size_t __which = _M_binmap[__bytes];
      _Bin_record& __bin = _M_bin[__which];
  
!     char* __c = __p - _M_get_align();
      _Block_record* __block = reinterpret_cast<_Block_record*>(__c);
        
      // Single threaded application - return to global pool.
*************** namespace __gnu_cxx
*** 91,117 ****
      const size_t __which = _M_binmap[__bytes];
      _Bin_record& __bin = _M_bin[__which];
      const _Tune& __options = _M_get_options();
!     const size_t __bin_size = ((__options._M_min_bin << __which) 
! 			       + __options._M_align);
!     size_t __block_count = __options._M_chunk_size / __bin_size;	  
  
      // Get a new block dynamically, set it up for use.
      void* __v = ::operator new(__options._M_chunk_size);
!     _Block_record* __block = static_cast<_Block_record*>(__v);
      __bin._M_first[__thread_id] = __block;
      while (--__block_count > 0)
        {
! 	char* __c = reinterpret_cast<char*>(__block) + __bin_size;
  	__block->_M_next = reinterpret_cast<_Block_record*>(__c);
  	__block = __block->_M_next;
        }
      __block->_M_next = NULL;
  
-     _Block_address* __address = new _Block_address;
-     __address->_M_initial = __v;
-     __address->_M_next = __bin._M_address;
-     __bin._M_address = __address;
- 
      __block = __bin._M_first[__thread_id];
      __bin._M_first[__thread_id] = __block->_M_next;
  
--- 89,117 ----
      const size_t __which = _M_binmap[__bytes];
      _Bin_record& __bin = _M_bin[__which];
      const _Tune& __options = _M_get_options();
!     const size_t __bin_size = (__options._M_min_bin << __which) 
! 			       + __options._M_align;
!     size_t __block_count = __options._M_chunk_size - sizeof(_Block_address);
!     __block_count /= __bin_size;	  
  
      // Get a new block dynamically, set it up for use.
      void* __v = ::operator new(__options._M_chunk_size);
!     _Block_address* __address = static_cast<_Block_address*>(__v);
!     __address->_M_initial = __v;
!     __address->_M_next = __bin._M_address;
!     __bin._M_address = __address;
! 
!     char* __c = static_cast<char*>(__v) + sizeof(_Block_address);
!     _Block_record* __block = reinterpret_cast<_Block_record*>(__c);
      __bin._M_first[__thread_id] = __block;
      while (--__block_count > 0)
        {
! 	__c += __bin_size;
  	__block->_M_next = reinterpret_cast<_Block_record*>(__c);
  	__block = __block->_M_next;
        }
      __block->_M_next = NULL;
  
      __block = __bin._M_first[__thread_id];
      __bin._M_first[__thread_id] = __block->_M_next;
  
*************** namespace __gnu_cxx
*** 187,193 ****
  		  {
  		    _Block_address* __tmp = __bin._M_address->_M_next;
  		    ::operator delete(__bin._M_address->_M_initial);
- 		    delete __bin._M_address;
  		    __bin._M_address = __tmp;
  		  }
  		::operator delete(__bin._M_first);
--- 187,192 ----
*************** namespace __gnu_cxx
*** 206,212 ****
  		  {
  		    _Block_address* __tmp = __bin._M_address->_M_next;
  		    ::operator delete(__bin._M_address->_M_initial);
- 		    delete __bin._M_address;
  		    __bin._M_address = __tmp;
  		  }
  		::operator delete(__bin._M_first);
--- 205,210 ----
*************** namespace __gnu_cxx
*** 224,231 ****
      const size_t __which = _M_binmap[__bytes];
      const _Bin_record& __bin = _M_bin[__which];
  
!     const _Tune& __options = _M_get_options();
!     char* __c = __p - __options._M_align;
      _Block_record* __block = reinterpret_cast<_Block_record*>(__c);
      if (__gthread_active_p())
        {
--- 222,229 ----
      const size_t __which = _M_binmap[__bytes];
      const _Bin_record& __bin = _M_bin[__which];
  
!     // Know __p not null, assume valid block.
!     char* __c = __p - _M_get_align();
      _Block_record* __block = reinterpret_cast<_Block_record*>(__c);
      if (__gthread_active_p())
        {
*************** namespace __gnu_cxx
*** 233,250 ****
  	// in order to avoid too much contention we wait until the
  	// number of records is "high enough".
  	const size_t __thread_id = _M_get_thread_id();
! 	
! 	long __remove = ((__bin._M_free[__thread_id] 
! 			  * __options._M_freelist_headroom)
! 			 - __bin._M_used[__thread_id]);
! 	if (__remove > static_cast<long>(100 * (_M_bin_size - __which)
! 					 * __options._M_freelist_headroom)
! 	    && __remove > static_cast<long>(__bin._M_free[__thread_id]))
  	  {
! 	    _Block_record* __tmp = __bin._M_first[__thread_id];
! 	    _Block_record* __first = __tmp;
  	    __remove /= __options._M_freelist_headroom;
! 	    const long __removed = __remove;
  	    while (--__remove > 0)
  	      __tmp = __tmp->_M_next;
  	    __bin._M_first[__thread_id] = __tmp->_M_next;
--- 231,252 ----
  	// in order to avoid too much contention we wait until the
  	// number of records is "high enough".
  	const size_t __thread_id = _M_get_thread_id();
! 	const _Tune& __options = _M_get_options();	
! 	const unsigned long __limit = 100 * (_M_bin_size - __which)
! 		                      * __options._M_freelist_headroom;
! 
! 	unsigned long __remove = __bin._M_free[__thread_id];
! 	__remove *= __options._M_freelist_headroom;
! 	if (__remove >= __bin._M_used[__thread_id])
! 	  __remove -= __bin._M_used[__thread_id];
! 	else
! 	  __remove = 0;
! 	if (__remove > __limit && __remove > __bin._M_free[__thread_id])
  	  {
! 	    _Block_record* __first = __bin._M_first[__thread_id];
! 	    _Block_record* __tmp = __first;
  	    __remove /= __options._M_freelist_headroom;
! 	    const unsigned long __removed = __remove;
  	    while (--__remove > 0)
  	      __tmp = __tmp->_M_next;
  	    __bin._M_first[__thread_id] = __tmp->_M_next;
*************** namespace __gnu_cxx
*** 256,262 ****
  	    __bin._M_free[0] += __removed;
  	    __gthread_mutex_unlock(__bin._M_mutex);
  	  }
! 	
  	// Return this block to our list and update counters and
  	// owner id as needed.
  	--__bin._M_used[__block->_M_thread_id];
--- 258,264 ----
  	    __bin._M_free[0] += __removed;
  	    __gthread_mutex_unlock(__bin._M_mutex);
  	  }
! 
  	// Return this block to our list and update counters and
  	// owner id as needed.
  	--__bin._M_used[__block->_M_thread_id];
*************** namespace __gnu_cxx
*** 283,289 ****
      const _Tune& __options = _M_get_options();
      const size_t __bin_size = ((__options._M_min_bin << __which)
  			       + __options._M_align);
!     size_t __block_count = __options._M_chunk_size / __bin_size;	  
      
      // Are we using threads?
      // - Yes, check if there are free blocks on the global
--- 285,292 ----
      const _Tune& __options = _M_get_options();
      const size_t __bin_size = ((__options._M_min_bin << __which)
  			       + __options._M_align);
!     size_t __block_count = __options._M_chunk_size - sizeof(_Block_address);
!     __block_count /= __bin_size;	  
      
      // Are we using threads?
      // - Yes, check if there are free blocks on the global
*************** namespace __gnu_cxx
*** 302,329 ****
  	__gthread_mutex_lock(__bin._M_mutex);
  	if (__bin._M_first[0] == NULL)
  	  {
! 	    // No need to hold the lock when we are adding a whole
! 	    // chunk to our own list.
  	    __gthread_mutex_unlock(__bin._M_mutex);
  
! 	    void* __v = ::operator new(__options._M_chunk_size);
! 	    __block = static_cast<_Block_record*>(__v);
  	    __bin._M_free[__thread_id] = __block_count;
  	    __bin._M_first[__thread_id] = __block;
  	    while (--__block_count > 0)
  	      {
! 		char* __c = reinterpret_cast<char*>(__block) + __bin_size;
  		__block->_M_next = reinterpret_cast<_Block_record*>(__c);
  		__block = __block->_M_next;
  	      }
  	    __block->_M_next = NULL;
- 
- 	    __gthread_mutex_lock(__bin._M_mutex);
- 	    _Block_address* __address = new _Block_address;
- 	    __address->_M_initial = __v;
- 	    __address->_M_next = __bin._M_address;
- 	    __bin._M_address = __address;
- 	    __gthread_mutex_unlock(__bin._M_mutex);
  	  }
  	else
  	  {
--- 305,330 ----
  	__gthread_mutex_lock(__bin._M_mutex);
  	if (__bin._M_first[0] == NULL)
  	  {
! 	    void* __v = ::operator new(__options._M_chunk_size);
! 	    _Block_address* __address = static_cast<_Block_address*>(__v);
! 	    __address->_M_initial = __v;
! 	    __address->_M_next = __bin._M_address;
! 	    __bin._M_address = __address;
  	    __gthread_mutex_unlock(__bin._M_mutex);
  
! 	    // No need to hold the lock when we are adding a whole
! 	    // chunk to our own list.
! 	    char* __c = static_cast<char*>(__v) + sizeof(_Block_address);
! 	    __block = reinterpret_cast<_Block_record*>(__c);
  	    __bin._M_free[__thread_id] = __block_count;
  	    __bin._M_first[__thread_id] = __block;
  	    while (--__block_count > 0)
  	      {
! 		__c += __bin_size;
  		__block->_M_next = reinterpret_cast<_Block_record*>(__c);
  		__block = __block->_M_next;
  	      }
  	    __block->_M_next = NULL;
  	  }
  	else
  	  {
*************** namespace __gnu_cxx
*** 353,372 ****
      else
        {
  	void* __v = ::operator new(__options._M_chunk_size);
! 	__block = static_cast<_Block_record*>(__v);
! 	__bin._M_first[0] = __block;
  	while (--__block_count > 0)
  	  {
! 	    char* __c = reinterpret_cast<char*>(__block) + __bin_size;
  	    __block->_M_next = reinterpret_cast<_Block_record*>(__c);
  	    __block = __block->_M_next;
  	  }
  	__block->_M_next = NULL;
- 
- 	_Block_address* __address = new _Block_address;
- 	__address->_M_initial = __v;
- 	__address->_M_next = __bin._M_address;
- 	__bin._M_address = __address;
        }
        
      __block = __bin._M_first[__thread_id];
--- 354,374 ----
      else
        {
  	void* __v = ::operator new(__options._M_chunk_size);
! 	_Block_address* __address = static_cast<_Block_address*>(__v);
! 	__address->_M_initial = __v;
! 	__address->_M_next = __bin._M_address;
! 	__bin._M_address = __address;
! 
! 	char* __c = static_cast<char*>(__v) + sizeof(_Block_address);
! 	_Block_record* __block = reinterpret_cast<_Block_record*>(__c);
!  	__bin._M_first[0] = __block;
  	while (--__block_count > 0)
  	  {
! 	    __c += __bin_size;
  	    __block->_M_next = reinterpret_cast<_Block_record*>(__c);
  	    __block = __block->_M_next;
  	  }
  	__block->_M_next = NULL;
        }
        
      __block = __bin._M_first[__thread_id];

^ permalink raw reply	[flat|nested] 2+ messages in thread

* [v3] __mt_alloc tweaks
@ 2004-10-14 20:52 Benjamin Kosnik
  0 siblings, 0 replies; 2+ messages in thread
From: Benjamin Kosnik @ 2004-10-14 20:52 UTC (permalink / raw)
  To: gcc-patches; +Cc: libstdc++

[-- Attachment #1: Type: text/plain, Size: 75 bytes --]


First in a series of patches, just consistency tweaks.

tested x86/linux


[-- Attachment #2: p.20041014 --]
[-- Type: text/plain, Size: 7300 bytes --]

2004-10-14  Benjamin Kosnik  <bkoz@redhat.com>

	* include/ext/mt_allocator.h: Tweaks.
	* src/mt_allocator.cc: Same.

Index: include/ext/mt_allocator.h
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/include/ext/mt_allocator.h,v
retrieving revision 1.37
diff -c -p -r1.37 mt_allocator.h
*** include/ext/mt_allocator.h	12 Oct 2004 01:10:38 -0000	1.37
--- include/ext/mt_allocator.h	14 Oct 2004 20:45:21 -0000
*************** namespace __gnu_cxx
*** 705,711 ****
  	  // Already reserved.
  	  typedef typename __pool_type::_Block_record _Block_record;
  	  _Block_record* __block = __bin._M_first[__thread_id];
! 	  __bin._M_first[__thread_id] = __bin._M_first[__thread_id]->_M_next;
  	  
  	  __pool._M_adjust_freelist(__bin, __block, __thread_id);
  	  const __pool_base::_Tune& __options = __pool._M_get_options();
--- 705,711 ----
  	  // Already reserved.
  	  typedef typename __pool_type::_Block_record _Block_record;
  	  _Block_record* __block = __bin._M_first[__thread_id];
! 	  __bin._M_first[__thread_id] = __block->_M_next;
  	  
  	  __pool._M_adjust_freelist(__bin, __block, __thread_id);
  	  const __pool_base::_Tune& __options = __pool._M_get_options();
Index: src/mt_allocator.cc
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/src/mt_allocator.cc,v
retrieving revision 1.5
diff -c -p -r1.5 mt_allocator.cc
*** src/mt_allocator.cc	12 Oct 2004 01:10:39 -0000	1.5
--- src/mt_allocator.cc	14 Oct 2004 20:45:22 -0000
*************** namespace __gnu_cxx
*** 89,94 ****
--- 89,95 ----
    {
      // Round up to power of 2 and figure out which bin to use.
      const size_t __which = _M_binmap[__bytes];
+     _Bin_record& __bin = _M_bin[__which];
      const _Tune& __options = _M_get_options();
      const size_t __bin_size = ((__options._M_min_bin << __which) 
  			       + __options._M_align);
*************** namespace __gnu_cxx
*** 97,120 ****
      // Get a new block dynamically, set it up for use.
      void* __v = ::operator new(__options._M_chunk_size);
      _Block_record* __block = static_cast<_Block_record*>(__v);
!     --__block_count;
!     _Block_record* __tmp = __block;
!     while (__block_count-- > 0)
        {
! 	char* __c = reinterpret_cast<char*>(__tmp) + __bin_size;
! 	__tmp->_M_next = reinterpret_cast<_Block_record*>(__c);
! 	__tmp = __tmp->_M_next;
        }
!     __tmp->_M_next = NULL;
  
-     // Update _Bin_record fields.
-     _Bin_record& __bin = _M_bin[__which];
-     __bin._M_first[__thread_id] = __block->_M_next;
      _Block_address* __address = new _Block_address;
      __address->_M_initial = __v;
      __address->_M_next = __bin._M_address;
      __bin._M_address = __address;
  
      // NB: For alignment reasons, we can't use the first _M_align
      // bytes, even when sizeof(_Block_record) < _M_align.
      return reinterpret_cast<char*>(__block) + __options._M_align;
--- 98,120 ----
      // Get a new block dynamically, set it up for use.
      void* __v = ::operator new(__options._M_chunk_size);
      _Block_record* __block = static_cast<_Block_record*>(__v);
!     __bin._M_first[__thread_id] = __block;
!     while (--__block_count > 0)
        {
! 	char* __c = reinterpret_cast<char*>(__block) + __bin_size;
! 	__block->_M_next = reinterpret_cast<_Block_record*>(__c);
! 	__block = __block->_M_next;
        }
!     __block->_M_next = NULL;
  
      _Block_address* __address = new _Block_address;
      __address->_M_initial = __v;
      __address->_M_next = __bin._M_address;
      __bin._M_address = __address;
  
+     __block = __bin._M_first[__thread_id];
+     __bin._M_first[__thread_id] = __block->_M_next;
+ 
      // NB: For alignment reasons, we can't use the first _M_align
      // bytes, even when sizeof(_Block_record) < _M_align.
      return reinterpret_cast<char*>(__block) + __options._M_align;
*************** namespace __gnu_cxx
*** 245,252 ****
  	    _Block_record* __first = __tmp;
  	    __remove /= __options._M_freelist_headroom;
  	    const long __removed = __remove;
! 	    --__remove;
! 	    while (__remove-- > 0)
  	      __tmp = __tmp->_M_next;
  	    __bin._M_first[__thread_id] = __tmp->_M_next;
  	    __bin._M_free[__thread_id] -= __removed;
--- 245,251 ----
  	    _Block_record* __first = __tmp;
  	    __remove /= __options._M_freelist_headroom;
  	    const long __removed = __remove;
! 	    while (--__remove > 0)
  	      __tmp = __tmp->_M_next;
  	    __bin._M_first[__thread_id] = __tmp->_M_next;
  	    __bin._M_free[__thread_id] -= __removed;
*************** namespace __gnu_cxx
*** 308,318 ****
  	    __gthread_mutex_unlock(__bin._M_mutex);
  
  	    void* __v = ::operator new(__options._M_chunk_size);
! 	    __bin._M_first[__thread_id] = static_cast<_Block_record*>(__v);
  	    __bin._M_free[__thread_id] = __block_count;
! 	    --__block_count;
! 	    __block = __bin._M_first[__thread_id];
! 	    while (__block_count-- > 0)
  	      {
  		char* __c = reinterpret_cast<char*>(__block) + __bin_size;
  		__block->_M_next = reinterpret_cast<_Block_record*>(__c);
--- 307,316 ----
  	    __gthread_mutex_unlock(__bin._M_mutex);
  
  	    void* __v = ::operator new(__options._M_chunk_size);
! 	    __block = static_cast<_Block_record*>(__v);
  	    __bin._M_free[__thread_id] = __block_count;
! 	    __bin._M_first[__thread_id] = __block;
! 	    while (--__block_count > 0)
  	      {
  		char* __c = reinterpret_cast<char*>(__block) + __bin_size;
  		__block->_M_next = reinterpret_cast<_Block_record*>(__c);
*************** namespace __gnu_cxx
*** 343,351 ****
  	      {
  		__bin._M_free[__thread_id] = __block_count;
  		__bin._M_free[0] -= __block_count;
- 		--__block_count;
  		__block = __bin._M_first[0];
! 		while (__block_count-- > 0)
  		  __block = __block->_M_next;
  		__bin._M_first[0] = __block->_M_next;
  		__block->_M_next = NULL;
--- 341,348 ----
  	      {
  		__bin._M_free[__thread_id] = __block_count;
  		__bin._M_free[0] -= __block_count;
  		__block = __bin._M_first[0];
! 		while (--__block_count > 0)
  		  __block = __block->_M_next;
  		__bin._M_first[0] = __block->_M_next;
  		__block->_M_next = NULL;
*************** namespace __gnu_cxx
*** 358,365 ****
  	void* __v = ::operator new(__options._M_chunk_size);
  	__block = static_cast<_Block_record*>(__v);
  	__bin._M_first[0] = __block;
! 	--__block_count;
! 	while (__block_count-- > 0)
  	  {
  	    char* __c = reinterpret_cast<char*>(__block) + __bin_size;
  	    __block->_M_next = reinterpret_cast<_Block_record*>(__c);
--- 355,361 ----
  	void* __v = ::operator new(__options._M_chunk_size);
  	__block = static_cast<_Block_record*>(__v);
  	__bin._M_first[0] = __block;
! 	while (--__block_count > 0)
  	  {
  	    char* __c = reinterpret_cast<char*>(__block) + __bin_size;
  	    __block->_M_next = reinterpret_cast<_Block_record*>(__c);
*************** namespace __gnu_cxx
*** 374,380 ****
        }
        
      __block = __bin._M_first[__thread_id];
!     __bin._M_first[__thread_id] = __bin._M_first[__thread_id]->_M_next;
  
      if (__gthread_active_p())
        {
--- 370,376 ----
        }
        
      __block = __bin._M_first[__thread_id];
!     __bin._M_first[__thread_id] = __block->_M_next;
  
      if (__gthread_active_p())
        {

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2004-10-17 15:28 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2004-10-17 16:03 [v3] __mt_alloc tweaks Benjamin Kosnik
  -- strict thread matches above, loose matches on Subject: below --
2004-10-14 20:52 Benjamin Kosnik

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).