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