Some performance numbers with different Allocators
Stefan Olsson
stefan@snon.net
Mon Jul 28 09:35:00 GMT 2003
Hi Abhi!
We have looked into this and the basic conclusion for the "poor
performance of __mt_allocator" is that this test only allocates new
memory, which then has to be fetched from the global pool thus forcing a
thread lock and a context switch. This becomes very obvious if you run a
vmstat 1 while running the tests...
However, in a real life application (?) you would both alloc and free
memory and end up with a freelist for each thread (in size relative to
the amount of memory allocated by that thread, thus limiting overall
memory usage) which then can be reused without locking/context switching.
If you really need to write an application such as the example I would
look into a allocator that maintains purely private freelists such as
the SGI pthread_alloc (see http://www.sgi.com/tech/stl/Allocators.html).
Brgds
/Stefan & Ola
Abhi wrote:
> I have some numbers for these tests with the gcc optimization flags
>
> with -O2 -funroll-loops
> =======================
> CPU malloc malloc STL normal STL MT
> & hoard
> 1 20.230u 1.580s 13.140u 0.970s 24.410u 13.390s 17.940u
> 7.660s
> 2 25.800u 1.810s 21.670u 0.750s 96.140u 142.020s 34.690u 26.670s
>
> Still hoard behaves better than STL MT allocators.
>
> These are for Redhat 7.3 LinuxThreads, gcc3.4
>
> thanks
> ...Abhi
>
>
>
>
> --On Wednesday, July 23, 2003 9:15 AM -0700 Abhi <abhi@qualcomm.com>
> wrote:
>
>> I ran these tests without any gcc optimization flags.
>> I will try with -O2 -funroll-loops and post results later today.
>> Do you want me to try with some other flags?
>>
>> I do believe my test is quite simplistic, It would be interesting to see
>> some results with more elaborate/complicated test cases.
>>
>> I will also posts results using Redhat 9 (with NPTL).
>>
>> Thanks
>> ....Abhi
>>
>>
>>
>> --On Wednesday, July 23, 2003 7:18 AM +0200 Stefan Olsson
>> <stefan@snon.net> wrote:
>>
>>> Hi Abhi!
>>>
>>> Very interesting since I did a similar test with Hoard about a year ago
>>> with very different results - thus the development of mt_allocator...
>>>
>>> Please let us know how you compiled the testprogram (optimization
>>> levels
>>> and other flags).
>>>
>>> Brgds
>>>
>>> /Stefan
>>>
>>> Abhi wrote:
>>>
>>>> Hi,
>>>> I ran some performace tests using different allocators.
>>>> The sample code is pretty simple,
>>>> - it creates 4 threads
>>>> - Each thread creates a list of string using an allocator
>>>> - Adds 1000000 strings to the list in a for loop
>>>> - Reads all these strings in a for loop
>>>> - Modifies all these strings in a for loop
>>>>
>>>> I ran this code 4 times (using 4 different allocators )
>>>> malloc = An allocator that uses malloc
>>>> malloc_hoard = An allocator that uses malloc with hoard (using
>>>> LD_PRELOAD, www.hoard.com)
>>>> STL = Default STL allocator that comes with gcc 3.4
>>>> (pool allocator)
>>>> STL MT = MT STL allocator that comes with gcc3.4
>>>>
>>>> Test Machine
>>>> Dual CPU, Linux Redhat 7.3, GCC3.4 snapshot
>>>>
>>>> Here are the numbers
>>>> # CPU malloc malloc_hoard STL STL MT
>>>>
>>>> 1 31.280u 1.500s 19.670u 0.900s 26.510u 13.470s 23.010u
>>>> 4.330s
>>>> 2 40.850u 2.270s 38.630u 0.710s 103.820u 148.150s 51.600u
>>>> 23.660s
>>>>
>>>> Seems like for this case hoard behaves the best, although a dual CPU
>>>> machine still performs worse that a single CPU machine for a MT
>>>> application. Does this seem surprising?
>>>>
>>>> Also I guess this code is MT-safe, especially the malloc
>>>> allocators...right? Just want to be sure!
>>>>
>>>> Heres the code
>>>> ----------------------------------------------------------------------
>>>> # include <list>
>>>> # include <pthread.h>
>>>> # include <errno.h> // ETIMEDOUT
>>>> # include <string>
>>>> // For malloc
>>>> // #include <ext/malloc_allocator.h>
>>>> // #include <bits/allocator_traits.h>
>>>> // For MT
>>>> // #include <ext/mt_allocator.h>
>>>> // #include <bits/allocator_traits.h>
>>>>
>>>>
>>>> using namespace std;
>>>>
>>>> // For Malloc
>>>> // typedef __allocator<char, __gnu_cxx::__malloc_alloc<0> >
>>>> MyAlloc;
>>>> // typedef basic_string<char, char_traits<char>, MyAlloc>
>>>> MyString;
>>>> // typedef std::list<MyString, __gnu_cxx::__malloc_alloc<1> > List1;
>>>>
>>>> // For MT
>>>> // typedef __allocator<char, __gnu_cxx::__mt_alloc<0> > MyAlloc;
>>>> // typedef basic_string<char, char_traits<char>, MyAlloc>
>>>> MyString;
>>>> // typedef std::list<MyString, __gnu_cxx::__mt_alloc<1> > List1;
>>>>
>>>>
>>>> // For Default STL
>>>> typedef string MyString;
>>>> typedef std::list<MyString> List1;
>>>>
>>>>
>>>>
>>>> extern "C" void* Run(void *)
>>>> {
>>>> List1 List;
>>>> for ( int i=0; i<1000000; ++i )
>>>> {
>>>> MyString s;
>>>> s.append("Hoiiiiiii");
>>>> List.push_back( s );
>>>> }
>>>>
>>>> for (List1::iterator j = List.begin(); j != List.end(); ++j)
>>>> {
>>>> MyString s = *j;
>>>> }
>>>>
>>>> for (List1::iterator j = List.begin(); j != List.end(); ++j)
>>>> {
>>>> MyString s("Hiiiiiii");
>>>> *j = s;
>>>> }
>>>>
>>>>
>>>> }
>>>>
>>>>
>>>> using namespace std;
>>>>
>>>> int main ()
>>>> {
>>>> pthread_t t1, t2, t3, t4;
>>>> pthread_create(&t1, // Thread Id for new thread
>>>> NULL, // Thread attributes
>>>> Run, // Function
>>>> NULL);
>>>>
>>>> pthread_create(&t2, // Thread Id for new thread
>>>> NULL, // Thread attributes
>>>> Run, // Function
>>>> NULL);
>>>>
>>>> pthread_create(&t3, // Thread Id for new thread
>>>> NULL, // Thread attributes
>>>> Run, // Function
>>>> NULL);
>>>>
>>>> pthread_create(&t4, // Thread Id for new thread
>>>> NULL, // Thread attributes
>>>> Run, // Function
>>>> NULL);
>>>>
>>>> int errNum = pthread_join(t1, NULL);
>>>> errNum = pthread_join(t2, NULL);
>>>> errNum = pthread_join(t3, NULL);
>>>> errNum = pthread_join(t4, NULL);
>>>> }
>>>>
>>>> ----------------------------------------------------------------------
>>>>
>>>> Any Insights/Ideas
>>>> Thanks
>>>> ....Abhi
>>>>
>>>>
>>>>
>>>
>>>
>>> --
>>> Winning isn't everything, but losing isn't anything.
>>>
>>
>>
>>
>
> ---------- End Abhi <abhi@qualcomm.com> Message ----------
>
>
>
>
>
--
Winning isn't everything, but losing isn't anything.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/x-pkcs7-signature
Size: 4660 bytes
Desc: S/MIME Cryptographic Signature
URL: <http://gcc.gnu.org/pipermail/libstdc++/attachments/20030728/838b2ab6/attachment.bin>
More information about the Libstdc++
mailing list