]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/container/bench/bench_alloc.cpp
update ceph source to reef 18.1.2
[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 #include <boost/core/no_exceptions_support.hpp>
17 #include <boost/container/throw_exception.hpp>
18
19 #define BOOST_INTERPROCESS_VECTOR_ALLOC_STATS
20
21 #include <iostream> //std::cout, std::endl
22 #include <typeinfo> //typeid
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 using namespace boost::container;
31
32 template <class POD>
33 void allocation_timing_test(std::size_t num_iterations, std::size_t num_elements)
34 {
35 size_t capacity = 0;
36 std::size_t numalloc = 0, numexpand = 0;
37
38 std::cout
39 << " ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ \n"
40 << " Iterations/Elements: " << num_iterations << "/" << num_elements << '\n'
41 << " ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ \n"
42 << std::endl;
43
44
45 allocation_type malloc_types[] = { BOOST_CONTAINER_EXPAND_BWD, BOOST_CONTAINER_EXPAND_FWD, BOOST_CONTAINER_ALLOCATE_NEW };
46 const char * malloc_names[] = { "Backwards expansion", "Forward expansion", "New allocation" };
47 for(size_t i = 0; i < sizeof(malloc_types)/sizeof(allocation_type); ++i){
48 numalloc = 0; numexpand = 0;
49 const allocation_type m_mode = malloc_types[i];
50 const char *malloc_name = malloc_names[i];
51
52 cpu_timer timer;
53 timer.resume();
54
55 for(std::size_t r = 0; r != num_iterations; ++r){
56 void *first_mem = 0;
57 if(m_mode != BOOST_CONTAINER_EXPAND_FWD)
58 first_mem = dlmalloc_malloc(sizeof(POD)*num_elements*3/2);
59 void *addr = dlmalloc_malloc(1*sizeof(POD));
60 if(m_mode == BOOST_CONTAINER_EXPAND_FWD)
61 first_mem = dlmalloc_malloc(sizeof(POD)*num_elements*3/2);
62 capacity = dlmalloc_size(addr)/sizeof(POD);
63 dlmalloc_free(first_mem);
64 ++numalloc;
65
66 BOOST_TRY{
67 dlmalloc_command_ret_t ret;
68 for(size_t e = capacity + 1; e < num_elements; ++e){
69 size_t received_size;
70 size_t min = (capacity+1)*sizeof(POD);
71 size_t max = (capacity*3/2)*sizeof(POD);
72 if(min > max)
73 max = min;
74 ret = dlmalloc_allocation_command
75 ( m_mode, sizeof(POD)
76 , min, max, &received_size, addr);
77 if(!ret.first){
78 throw_runtime_error("!ret.first)");
79 }
80 if(!ret.second){
81 assert(m_mode == BOOST_CONTAINER_ALLOCATE_NEW);
82 if(m_mode != BOOST_CONTAINER_ALLOCATE_NEW){
83 std::cout << "m_mode != BOOST_CONTAINER_ALLOCATE_NEW!" << std::endl;
84 return;
85 }
86 dlmalloc_free(addr);
87 addr = ret.first;
88 ++numalloc;
89 }
90 else{
91 assert(m_mode != BOOST_CONTAINER_ALLOCATE_NEW);
92 if(m_mode == BOOST_CONTAINER_ALLOCATE_NEW){
93 std::cout << "m_mode == BOOST_CONTAINER_ALLOCATE_NEW!" << std::endl;
94 return;
95 }
96 ++numexpand;
97 }
98 capacity = received_size/sizeof(POD);
99 addr = ret.first;
100 e = capacity + 1;
101 }
102 dlmalloc_free(addr);
103 }
104 BOOST_CATCH(...){
105 dlmalloc_free(addr);
106 BOOST_RETHROW;
107 }
108 BOOST_CATCH_END
109 }
110
111 assert( dlmalloc_allocated_memory() == 0);
112 if(dlmalloc_allocated_memory()!= 0){
113 std::cout << "Memory leak!" << std::endl;
114 return;
115 }
116
117 timer.stop();
118 nanosecond_type nseconds = timer.elapsed().wall;
119
120 std::cout << " Malloc type: " << malloc_name
121 << std::endl
122 << " allocation ns: "
123 << float(nseconds)/float(num_iterations*num_elements)
124 << std::endl
125 << " capacity - alloc calls (new/expand): "
126 << (std::size_t)capacity << " - "
127 << (float(numalloc) + float(numexpand))/float(num_iterations)
128 << "(" << float(numalloc)/float(num_iterations) << "/" << float(numexpand)/float(num_iterations) << ")"
129 << std::endl << std::endl;
130 dlmalloc_trim(0);
131 }
132 }
133
134 template<unsigned N>
135 struct char_holder
136 {
137 char ints_[N];
138 };
139
140 template<class POD>
141 int allocation_loop()
142 {
143 std::cout << std::endl
144 << "-------------------------------------------\n"
145 << "-------------------------------------------\n"
146 << " Type(sizeof): " << typeid(POD).name() << " (" << sizeof(POD) << ")\n"
147 << "-------------------------------------------\n"
148 << "-------------------------------------------\n"
149 << std::endl;
150
151 //#define SINGLE_TEST
152 #define SIMPLE_IT
153 #ifdef SINGLE_TEST
154 #ifdef NDEBUG
155 std::size_t numrep [] = { 50000 };
156 #else
157 std::size_t numrep [] = { 5000 };
158 #endif
159 std::size_t numele [] = { 100 };
160 #elif defined(SIMPLE_IT)
161 std::size_t numrep [] = { 3 };
162 std::size_t numele [] = { 100 };
163 #else
164 #ifdef NDEBUG
165 std::size_t numrep [] = { /*10000, */10000, 100000, 1000000 };
166 #else
167 std::size_t numrep [] = { /*10000, */1000, 10000, 100000 };
168 #endif
169 std::size_t numele [] = { /*10000, */1000, 100, 10 };
170 #endif
171
172 for(std::size_t i = 0; i < sizeof(numele)/sizeof(numele[0]); ++i){
173 allocation_timing_test<POD>(numrep[i], numele[i]);
174 }
175
176 return 0;
177 }
178
179 int main()
180 {
181 dlmalloc_mallopt( (-3)//M_MMAP_THRESHOLD
182 , 100*10000000);
183 //allocation_loop<char_holder<4> >();
184 //allocation_loop<char_holder<6> >();
185 allocation_loop<char_holder<8> >();
186 allocation_loop<char_holder<12> >();
187 //allocation_loop<char_holder<14> >();
188 allocation_loop<char_holder<24> >();
189 return 0;
190 }