]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/container/bench/bench_alloc_expand_bwd.cpp
import quincy beta 17.1.0
[ceph.git] / ceph / src / boost / libs / container / bench / bench_alloc_expand_bwd.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/allocator.hpp>
16 #include <boost/core/no_exceptions_support.hpp>
17
18 #define BOOST_CONTAINER_VECTOR_ALLOC_STATS
19
20 #include <boost/container/vector.hpp>
21 #include <memory> //std::allocator
22 #include <iostream> //std::cout, std::endl
23 #include <cassert> //assert
24
25 #include <boost/move/detail/nsec_clock.hpp>
26 using boost::move_detail::cpu_timer;
27 using boost::move_detail::cpu_times;
28 using boost::move_detail::nanosecond_type;
29
30 namespace bc = boost::container;
31
32 typedef std::allocator<int> StdAllocator;
33 typedef bc::allocator<int, 2, bc::expand_bwd | bc::expand_fwd> AllocatorPlusV2Mask;
34 typedef bc::allocator<int, 2, bc::expand_fwd> AllocatorPlusV2;
35 typedef bc::allocator<int, 1> AllocatorPlusV1;
36
37 template<class Allocator> struct get_allocator_name;
38
39 template<> struct get_allocator_name<StdAllocator>
40 { static const char *get() { return "StdAllocator"; } };
41
42 template<> struct get_allocator_name<AllocatorPlusV2Mask>
43 { static const char *get() { return "AllocatorPlusV2Mask"; } };
44
45 template<> struct get_allocator_name<AllocatorPlusV2>
46 { static const char *get() { return "AllocatorPlusV2"; } };
47
48 template<> struct get_allocator_name<AllocatorPlusV1>
49 { static const char *get() { return "AllocatorPlusV1"; } };
50
51 //typedef int MyInt;
52
53 class MyInt
54 {
55 int int_;
56
57 public:
58 MyInt(int i = 0)
59 : int_(i)
60 {}
61
62 MyInt(const MyInt &other)
63 : int_(other.int_)
64 {}
65
66 MyInt & operator=(const MyInt &other)
67 {
68 int_ = other.int_;
69 return *this;
70 }
71
72 ~MyInt()
73 {
74 int_ = 0;
75 }
76 };
77 namespace boost{
78
79 template<class T>
80 struct has_trivial_destructor_after_move;
81
82 template<>
83 struct has_trivial_destructor_after_move<MyInt>
84 {
85 static const bool value = true;
86 //static const bool value = false;
87 };
88
89 } //namespace boost{
90
91
92 void print_header()
93 {
94 std::cout << "Allocator" << ";" << "Iterations" << ";" << "Size" << ";"
95 << "Capacity" << ";" << "push_back(ns)" << ";" << "Allocator calls" << ";"
96 << "New allocations" << ";" << "Bwd expansions" << std::endl;
97 }
98
99 template<class Allocator>
100 void vector_test_template(unsigned int num_iterations, unsigned int num_elements, bool csv_output)
101 {
102 typedef typename Allocator::template rebind<MyInt>::other IntAllocator;
103 unsigned int numalloc = 0, numexpand = 0;
104
105 cpu_timer timer;
106 timer.resume();
107
108 unsigned int capacity = 0;
109 for(unsigned int r = 0; r != num_iterations; ++r){
110 bc::vector<MyInt, IntAllocator> v;
111 v.reset_alloc_stats();
112 void *first_mem = 0;
113 BOOST_TRY{
114 first_mem = bc::dlmalloc_malloc(sizeof(MyInt)*num_elements*3/2);
115 v.push_back(MyInt(0));
116 bc::dlmalloc_free(first_mem);
117
118 for(unsigned int e = 0; e != num_elements; ++e){
119 v.push_back(MyInt(e));
120 }
121 numalloc += v.num_alloc;
122 numexpand += v.num_expand_bwd;
123 capacity = static_cast<unsigned int>(v.capacity());
124 }
125 BOOST_CATCH(...){
126 bc::dlmalloc_free(first_mem);
127 BOOST_RETHROW;
128 }
129 BOOST_CATCH_END
130 }
131
132 assert(bc::dlmalloc_allocated_memory() == 0);
133
134 timer.stop();
135 nanosecond_type nseconds = timer.elapsed().wall;
136
137 if(csv_output){
138 std::cout << get_allocator_name<Allocator>::get()
139 << ";"
140 << num_iterations
141 << ";"
142 << num_elements
143 << ";"
144 << capacity
145 << ";"
146 << float(nseconds)/(num_iterations*num_elements)
147 << ";"
148 << (float(numalloc) + float(numexpand))/num_iterations
149 << ";"
150 << float(numalloc)/num_iterations
151 << ";"
152 << float(numexpand)/num_iterations
153 << std::endl;
154 }
155 else{
156 std::cout << std::endl
157 << "Allocator: " << get_allocator_name<Allocator>::get()
158 << std::endl
159 << " push_back ns: "
160 << float(nseconds)/(num_iterations*num_elements)
161 << std::endl
162 << " capacity - alloc calls (new/expand): "
163 << (unsigned int)capacity << " - "
164 << (float(numalloc) + float(numexpand))/num_iterations
165 << "(" << float(numalloc)/num_iterations << "/" << float(numexpand)/num_iterations << ")"
166 << std::endl;
167 std::cout << '\n'
168 << " ----------------------------------- "
169 << std::endl;
170 }
171 bc::dlmalloc_trim(0);
172 }
173
174 int main(int argc, const char *argv[])
175 {
176 //#define SINGLE_TEST
177 #define SIMPLE_IT
178 #ifdef SINGLE_TEST
179 #ifdef NDEBUG
180 unsigned int numit [] = { 10 };
181 #else
182 unsigned int numit [] = { 10 };
183 #endif
184 unsigned int numele [] = { 10000 };
185 #elif defined(SIMPLE_IT)
186 unsigned int numit [] = { 3 };
187 unsigned int numele[] = { 10000 };
188 #else
189 #ifdef NDEBUG
190 unsigned int numit [] = { 2000, 20000, 200000, 2000000 };
191 #else
192 unsigned int numit [] = { 100, 1000, 10000, 100000 };
193 #endif
194 unsigned int numele [] = { 10000, 1000, 100, 10 };
195 #endif
196
197 bool csv_output = argc == 2 && (strcmp(argv[1], "--csv-output") == 0);
198
199 if(csv_output){
200 print_header();
201 for(unsigned int i = 0; i < sizeof(numele)/sizeof(numele[0]); ++i){
202 vector_test_template<StdAllocator>(numit[i], numele[i], csv_output);
203 }
204 for(unsigned int i = 0; i < sizeof(numele)/sizeof(numele[0]); ++i){
205 vector_test_template<AllocatorPlusV1>(numit[i], numele[i], csv_output);
206 }
207 for(unsigned int i = 0; i < sizeof(numele)/sizeof(numele[0]); ++i){
208 vector_test_template<AllocatorPlusV2Mask>(numit[i], numele[i], csv_output);
209 }
210 for(unsigned int i = 0; i < sizeof(numele)/sizeof(numele[0]); ++i){
211 vector_test_template<AllocatorPlusV2>(numit[i], numele[i], csv_output);
212 }
213 }
214 else{
215 for(unsigned int i = 0; i < sizeof(numele)/sizeof(numele[0]); ++i){
216 std::cout << "\n ----------------------------------- \n"
217 << " Iterations/Elements: " << numit[i] << "/" << numele[i]
218 << "\n ----------------------------------- \n";
219 vector_test_template<StdAllocator>(numit[i], numele[i], csv_output);
220 vector_test_template<AllocatorPlusV1>(numit[i], numele[i], csv_output);
221 vector_test_template<AllocatorPlusV2Mask>(numit[i], numele[i], csv_output);
222 vector_test_template<AllocatorPlusV2>(numit[i], numele[i], csv_output);
223 }
224 }
225 return 0;
226 }