* [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).