]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | ////////////////////////////////////////////////////////////////////////////// |
2 | // | |
3 | // (C) Copyright Ion Gaztanaga 2007-2013. Distributed under the Boost | |
4 | // Software License, Version 1.0. (See accompanying file | |
5 | // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | |
6 | // | |
7 | // See http://www.boost.org/libs/container for documentation. | |
8 | // | |
9 | ////////////////////////////////////////////////////////////////////////////// | |
10 | ||
11 | #ifdef _MSC_VER | |
12 | #pragma warning (disable : 4512) | |
13 | #endif | |
14 | ||
15 | #include <boost/container/detail/dlmalloc.hpp> | |
16 | ||
17 | #define BOOST_INTERPROCESS_VECTOR_ALLOC_STATS | |
18 | ||
19 | #include <iostream> //std::cout, std::endl | |
20 | #include <typeinfo> //typeid | |
21 | #include <cassert> //assert | |
22 | ||
23 | #include <boost/timer/timer.hpp> | |
24 | using boost::timer::cpu_timer; | |
25 | using boost::timer::cpu_times; | |
26 | using boost::timer::nanosecond_type; | |
27 | ||
28 | using namespace boost::container; | |
29 | ||
30 | template <class POD> | |
31 | void allocation_timing_test(unsigned int num_iterations, unsigned int num_elements) | |
32 | { | |
33 | size_t capacity = 0; | |
34 | unsigned int numalloc = 0, numexpand = 0; | |
35 | ||
36 | std::cout | |
37 | << " ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ \n" | |
38 | << " Iterations/Elements: " << num_iterations << "/" << num_elements << '\n' | |
39 | << " ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ \n" | |
40 | << std::endl; | |
41 | ||
42 | ||
43 | allocation_type malloc_types[] = { BOOST_CONTAINER_EXPAND_BWD, BOOST_CONTAINER_EXPAND_FWD, BOOST_CONTAINER_ALLOCATE_NEW }; | |
44 | const char * malloc_names[] = { "Backwards expansion", "Forward expansion", "New allocation" }; | |
45 | for(size_t i = 0; i < sizeof(malloc_types)/sizeof(allocation_type); ++i){ | |
46 | numalloc = 0; numexpand = 0; | |
47 | const allocation_type m_mode = malloc_types[i]; | |
48 | const char *malloc_name = malloc_names[i]; | |
49 | ||
50 | cpu_timer timer; | |
51 | timer.resume(); | |
52 | ||
53 | for(unsigned int r = 0; r != num_iterations; ++r){ | |
54 | void *first_mem = 0; | |
55 | if(m_mode != BOOST_CONTAINER_EXPAND_FWD) | |
56 | first_mem = dlmalloc_malloc(sizeof(POD)*num_elements*3/2); | |
57 | void *addr = dlmalloc_malloc(1*sizeof(POD)); | |
58 | if(m_mode == BOOST_CONTAINER_EXPAND_FWD) | |
59 | first_mem = dlmalloc_malloc(sizeof(POD)*num_elements*3/2); | |
60 | capacity = dlmalloc_size(addr)/sizeof(POD); | |
61 | dlmalloc_free(first_mem); | |
62 | ++numalloc; | |
63 | ||
64 | try{ | |
65 | dlmalloc_command_ret_t ret; | |
66 | for(size_t e = capacity + 1; e < num_elements; ++e){ | |
67 | size_t received_size; | |
68 | size_t min = (capacity+1)*sizeof(POD); | |
69 | size_t max = (capacity*3/2)*sizeof(POD); | |
70 | if(min > max) | |
71 | max = min; | |
72 | ret = dlmalloc_allocation_command | |
73 | ( m_mode, sizeof(POD) | |
74 | , min, max, &received_size, addr); | |
75 | if(!ret.first){ | |
76 | std::cout << "(!ret.first)!" << std::endl; | |
77 | throw int(0); | |
78 | } | |
79 | if(!ret.second){ | |
80 | assert(m_mode == BOOST_CONTAINER_ALLOCATE_NEW); | |
81 | if(m_mode != BOOST_CONTAINER_ALLOCATE_NEW){ | |
82 | std::cout << "m_mode != BOOST_CONTAINER_ALLOCATE_NEW!" << std::endl; | |
83 | return; | |
84 | } | |
85 | dlmalloc_free(addr); | |
86 | addr = ret.first; | |
87 | ++numalloc; | |
88 | } | |
89 | else{ | |
90 | assert(m_mode != BOOST_CONTAINER_ALLOCATE_NEW); | |
91 | if(m_mode == BOOST_CONTAINER_ALLOCATE_NEW){ | |
92 | std::cout << "m_mode == BOOST_CONTAINER_ALLOCATE_NEW!" << std::endl; | |
93 | return; | |
94 | } | |
95 | ++numexpand; | |
96 | } | |
97 | capacity = received_size/sizeof(POD); | |
98 | addr = ret.first; | |
99 | e = capacity + 1; | |
100 | } | |
101 | dlmalloc_free(addr); | |
102 | } | |
103 | catch(...){ | |
104 | dlmalloc_free(addr); | |
105 | throw; | |
106 | } | |
107 | } | |
108 | ||
109 | assert( dlmalloc_allocated_memory() == 0); | |
110 | if(dlmalloc_allocated_memory()!= 0){ | |
111 | std::cout << "Memory leak!" << std::endl; | |
112 | return; | |
113 | } | |
114 | ||
115 | timer.stop(); | |
116 | nanosecond_type nseconds = timer.elapsed().wall; | |
117 | ||
118 | std::cout << " Malloc type: " << malloc_name | |
119 | << std::endl | |
120 | << " allocation ns: " | |
121 | << float(nseconds)/(num_iterations*num_elements) | |
122 | << std::endl | |
123 | << " capacity - alloc calls (new/expand): " | |
124 | << (unsigned int)capacity << " - " | |
125 | << (float(numalloc) + float(numexpand))/num_iterations | |
126 | << "(" << float(numalloc)/num_iterations << "/" << float(numexpand)/num_iterations << ")" | |
127 | << std::endl << std::endl; | |
128 | dlmalloc_trim(0); | |
129 | } | |
130 | } | |
131 | ||
132 | template<unsigned N> | |
133 | struct char_holder | |
134 | { | |
135 | char ints_[N]; | |
136 | }; | |
137 | ||
138 | template<class POD> | |
139 | int allocation_loop() | |
140 | { | |
141 | std::cout << std::endl | |
142 | << "-------------------------------------------\n" | |
143 | << "-------------------------------------------\n" | |
144 | << " Type(sizeof): " << typeid(POD).name() << " (" << sizeof(POD) << ")\n" | |
145 | << "-------------------------------------------\n" | |
146 | << "-------------------------------------------\n" | |
147 | << std::endl; | |
148 | ||
92f5a8d4 TL |
149 | //#define SINGLE_TEST |
150 | #define SIMPLE_IT | |
151 | #ifdef SINGLE_TEST | |
7c673cae | 152 | #ifdef NDEBUG |
92f5a8d4 | 153 | unsigned int numrep [] = { 50000 }; |
7c673cae | 154 | #else |
92f5a8d4 | 155 | unsigned int numrep [] = { 5000 }; |
7c673cae | 156 | #endif |
92f5a8d4 TL |
157 | unsigned int numele [] = { 100 }; |
158 | #elif defined(SIMPLE_IT) | |
159 | unsigned int numrep [] = { 3 }; | |
160 | unsigned int numele [] = { 100 }; | |
7c673cae FG |
161 | #else |
162 | #ifdef NDEBUG | |
92f5a8d4 | 163 | unsigned int numrep [] = { /*10000, */10000, 100000, 1000000 }; |
7c673cae | 164 | #else |
92f5a8d4 | 165 | unsigned int numrep [] = { /*10000, */1000, 10000, 100000 }; |
7c673cae | 166 | #endif |
92f5a8d4 | 167 | unsigned int numele [] = { /*10000, */1000, 100, 10 }; |
7c673cae FG |
168 | #endif |
169 | ||
170 | for(unsigned int i = 0; i < sizeof(numele)/sizeof(numele[0]); ++i){ | |
171 | allocation_timing_test<POD>(numrep[i], numele[i]); | |
172 | } | |
173 | ||
174 | return 0; | |
175 | } | |
176 | ||
177 | int main() | |
178 | { | |
179 | dlmalloc_mallopt( (-3)//M_MMAP_THRESHOLD | |
180 | , 100*10000000); | |
181 | //allocation_loop<char_holder<4> >(); | |
182 | //allocation_loop<char_holder<6> >(); | |
183 | allocation_loop<char_holder<8> >(); | |
184 | allocation_loop<char_holder<12> >(); | |
185 | //allocation_loop<char_holder<14> >(); | |
186 | allocation_loop<char_holder<24> >(); | |
187 | return 0; | |
188 | } |