]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/container/bench/bench_alloc.cpp
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / container / bench / bench_alloc.cpp
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
149 #define SINGLE_TEST
150 #ifndef SINGLE_TEST
151 #ifdef NDEBUG
152 unsigned int numrep [] = { /*10000, */10000, 100000, 1000000 };
153 #else
154 unsigned int numrep [] = { /*10000, */1000, 10000, 100000 };
155 #endif
156 unsigned int numele [] = { /*10000, */1000, 100, 10 };
157 #else
158 #ifdef NDEBUG
159 unsigned int numrep [] = { 50000 };
160 #else
161 unsigned int numrep [] = { 5000 };
162 #endif
163 unsigned int numele [] = { 100 };
164 #endif
165
166 for(unsigned int i = 0; i < sizeof(numele)/sizeof(numele[0]); ++i){
167 allocation_timing_test<POD>(numrep[i], numele[i]);
168 }
169
170 return 0;
171 }
172
173 int main()
174 {
175 dlmalloc_mallopt( (-3)//M_MMAP_THRESHOLD
176 , 100*10000000);
177 //allocation_loop<char_holder<4> >();
178 //allocation_loop<char_holder<6> >();
179 allocation_loop<char_holder<8> >();
180 allocation_loop<char_holder<12> >();
181 //allocation_loop<char_holder<14> >();
182 allocation_loop<char_holder<24> >();
183 return 0;
184 }