Skip to content

Commit 075b4f7

Browse files
committed
Unify common bench types into the bench_utils.hpp header
1 parent 7b78262 commit 075b4f7

9 files changed

Lines changed: 138 additions & 113 deletions

bench/bench_adaptive_node_pool.cpp

Lines changed: 3 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,8 @@
3030
#include <cassert> //assert
3131

3232
#include <boost/move/detail/nsec_clock.hpp>
33+
#include "bench_utils.hpp" //MyInt
3334

34-
using boost::move_detail::cpu_timer;
3535
using boost::move_detail::cpu_times;
3636
using boost::move_detail::nanosecond_type;
3737

@@ -115,22 +115,6 @@ template<> struct get_allocator_name<SimpleSegregatedStorageV1>
115115
template<> struct get_allocator_name<SimpleSegregatedStorageV2>
116116
{ static const char *get() { return "SimpleSegregatedStorageV2"; } };
117117

118-
class MyInt
119-
{
120-
std::size_t int_;
121-
122-
public:
123-
explicit MyInt(std::size_t i = 0) : int_(i){}
124-
MyInt(const MyInt &other)
125-
: int_(other.int_)
126-
{}
127-
MyInt & operator=(const MyInt &other)
128-
{
129-
int_ = other.int_;
130-
return *this;
131-
}
132-
};
133-
134118
template<class Allocator>
135119
void list_test_template(std::size_t num_iterations, std::size_t num_elements, bool csv_output)
136120
{
@@ -143,11 +127,11 @@ void list_test_template(std::size_t num_iterations, std::size_t num_elements, bo
143127
typedef bc::list<MyInt, IntAllocator> list_t;
144128
typedef typename list_t::iterator iterator_t;
145129
{
146-
cpu_timer timer;
130+
boost::move_detail::cpu_timer timer;
147131
timer.resume();
148132
list_t l;
149133
for(std::size_t r = 0; r != num_iterations; ++r){
150-
l.insert(l.end(), num_elements, MyInt(r));
134+
l.insert(l.end(), num_elements, MyInt((int)r));
151135
}
152136
timer.stop();
153137
tinsert = timer.elapsed().wall;

bench/bench_alloc_expand_bwd.cpp

Lines changed: 3 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -23,36 +23,11 @@
2323

2424
#include <boost/move/detail/nsec_clock.hpp>
2525

26-
using boost::move_detail::cpu_timer;
26+
#include "bench_utils.hpp" //MyInt
27+
2728
using boost::move_detail::cpu_times;
2829
using boost::move_detail::nanosecond_type;
2930

30-
//typedef int MyInt;
31-
32-
class MyInt
33-
{
34-
int int_;
35-
36-
public:
37-
MyInt(int i = 0)
38-
: int_(i)
39-
{}
40-
41-
MyInt(const MyInt &other)
42-
: int_(other.int_)
43-
{}
44-
45-
MyInt & operator=(const MyInt &other)
46-
{
47-
int_ = other.int_;
48-
return *this;
49-
}
50-
51-
~MyInt()
52-
{
53-
int_ = 0;
54-
}
55-
};
5631
namespace boost{
5732

5833
template<class T>
@@ -105,7 +80,7 @@ void vector_test_template(std::size_t num_iterations, std::size_t num_elements,
10580
typedef Allocator IntAllocator;
10681
std::size_t numalloc = 0, numexpand = 0;
10782

108-
cpu_timer timer;
83+
boost::move_detail::cpu_timer timer;
10984
timer.resume();
11085

11186
std::size_t capacity = 0;

bench/bench_alloc_expand_fwd.cpp

Lines changed: 2 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
#include <cstring> //std::strcmp
2626
#include <boost/move/detail/nsec_clock.hpp>
2727
#include <typeinfo>
28-
using boost::move_detail::cpu_timer;
28+
#include "bench_utils.hpp" //MyInt
2929
using boost::move_detail::cpu_times;
3030
using boost::move_detail::nanosecond_type;
3131

@@ -59,37 +59,12 @@ static std::size_t get_num_expand(bc::vector<T, Allocator> &v)
5959

6060
#endif //BOOST_CONTAINER_VECTOR_ALLOC_STATS
6161

62-
class MyInt
63-
{
64-
int int_;
65-
66-
public:
67-
explicit MyInt(int i = 0)
68-
: int_(i)
69-
{}
70-
71-
MyInt(const MyInt &other)
72-
: int_(other.int_)
73-
{}
74-
75-
MyInt & operator=(const MyInt &other)
76-
{
77-
int_ = other.int_;
78-
return *this;
79-
}
80-
81-
~MyInt()
82-
{
83-
int_ = 0;
84-
}
85-
};
86-
8762
template<class Container>
8863
void vector_test_template(std::size_t num_iterations, std::size_t num_elements)
8964
{
9065
std::size_t numalloc = 0, numexpand = 0;
9166

92-
cpu_timer timer;
67+
boost::move_detail::cpu_timer timer;
9368
timer.resume();
9469

9570
std::size_t capacity = 0;

bench/bench_alloc_shrink_to_fit.cpp

Lines changed: 9 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -25,30 +25,12 @@
2525
#include <cassert> //assert
2626

2727
#include <boost/move/detail/nsec_clock.hpp>
28-
using boost::move_detail::cpu_timer;
28+
#include "bench_utils.hpp" //MyInt
2929
using boost::move_detail::cpu_times;
3030
using boost::move_detail::nanosecond_type;
3131

3232
namespace bc = boost::container;
3333

34-
class MyInt
35-
{
36-
std::ptrdiff_t int_; //Use a type that will grow on 64 bit machines
37-
38-
public:
39-
MyInt(int i = 0) : int_(i){}
40-
41-
MyInt(const MyInt &other)
42-
: int_(other.int_)
43-
{}
44-
45-
MyInt & operator=(const MyInt &other)
46-
{
47-
int_ = other.int_;
48-
return *this;
49-
}
50-
};
51-
5234
typedef std::allocator<MyInt> StdAllocator;
5335
typedef bc::allocator<MyInt, 2> AllocatorPlusV2;
5436
typedef bc::allocator<MyInt, 1> AllocatorPlusV1;
@@ -76,11 +58,17 @@ void vector_test_template(std::size_t num_iterations, std::size_t num_elements,
7658
typedef Allocator IntAllocator;
7759

7860
std::size_t capacity = 0;
79-
const std::size_t Step = 5;
61+
//Erase enough elements per iteration to free ~40 bytes (as the original
62+
//8-byte element x Step 5 did). A version-2 allocator can only shrink in
63+
//place once the freed region reaches dlmalloc's chunk granularity (16 bytes
64+
//on 64-bit); a smaller step (e.g. a 4-byte element x 5 = 20 bytes) fails to
65+
//cross a chunk boundary every iteration, so v.num_shrink would not advance
66+
//and the assertion below would fire. Step is kept a divisor of num_elements.
67+
const std::size_t Step = 40u/sizeof(MyInt) ? 40u/sizeof(MyInt) : 1u;
8068
std::size_t num_shrink = 0;
8169
(void)capacity;
8270

83-
cpu_timer timer;
71+
boost::move_detail::cpu_timer timer;
8472
timer.resume();
8573

8674
#ifndef NDEBUG

bench/bench_alloc_stable_vector_burst.cpp

Lines changed: 2 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -27,29 +27,13 @@
2727
#include <boost/container/stable_vector.hpp>
2828
#include <boost/container/vector.hpp>
2929
#include <boost/move/detail/nsec_clock.hpp>
30+
#include "bench_utils.hpp" //MyInt
3031

31-
using boost::move_detail::cpu_timer;
3232
using boost::move_detail::cpu_times;
3333
using boost::move_detail::nanosecond_type;
3434

3535
namespace bc = boost::container;
3636

37-
class MyInt
38-
{
39-
int int_;
40-
41-
public:
42-
MyInt(int i = 0) : int_(i){}
43-
MyInt(const MyInt &other)
44-
: int_(other.int_)
45-
{}
46-
MyInt & operator=(const MyInt &other)
47-
{
48-
int_ = other.int_;
49-
return *this;
50-
}
51-
};
52-
5337
typedef std::allocator<MyInt> StdAllocator;
5438
typedef bc::allocator<MyInt, 1> AllocatorPlusV1;
5539
typedef bc::allocator<MyInt, 2> AllocatorPlusV2;
@@ -104,7 +88,7 @@ void stable_vector_test_template(std::size_t num_iterations, std::size_t num_ele
10488
{
10589
{
10690
vector_type l;
107-
cpu_timer timer;
91+
boost::move_detail::cpu_timer timer;
10892
timer.resume();
10993

11094
for(std::size_t r = 0; r != num_iterations; ++r){

bench/bench_small_vector.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@
1313
//
1414
//////////////////////////////////////////////////////////////////////////////
1515

16+
#ifndef LONG_BENCH
17+
//#define LONG_BENCH
18+
#endif
19+
1620
#include <vector>
1721
#include <memory> //std::allocator
1822
#include <boost/container/vector.hpp>

bench/bench_static_vector.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@
1313
//
1414
//////////////////////////////////////////////////////////////////////////////
1515

16+
#ifndef LONG_BENCH
17+
//#define LONG_BENCH
18+
#endif
19+
1620
#include <vector>
1721
#include <memory> //std::allocator
1822
#include <boost/container/vector.hpp>

bench/bench_utils.hpp

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,11 @@
1212
#define BOOST_CONTAINER_BENCH_UTILS_HPP
1313

1414
#include <boost/move/detail/nsec_clock.hpp>
15+
#include <boost/move/utility_core.hpp>
1516
#include <boost/container/detail/workaround.hpp>
17+
#include <algorithm>
18+
#include <cstddef>
19+
#include <cstring>
1620
#include <vector>
1721

1822
volatile int bench_utils_sink = 0;
@@ -124,4 +128,110 @@ typedef boost::move_detail::cpu_timer cpu_timer;
124128
BOOST_CONTAINER_FORCEINLINE void clobber() { BOOST_CONTAINER_BENCH_CLOBBER(); }
125129
BOOST_CONTAINER_FORCEINLINE void escape(void* p) { BOOST_CONTAINER_BENCH_ESCAPE(p); }
126130

131+
///////////////////////////////////////////////////////////////////////////////
132+
// Shared benchmark element types.
133+
//
134+
// MyInt: a non-trivial "int wrapper" used by several benchmarks to exercise the
135+
// non-trivially-copyable element code paths (its user-provided copy ctor, copy
136+
// assignment and destructor disable the trivial memcpy/relocation fast paths),
137+
// as opposed to a plain int. This single definition replaces the per-benchmark
138+
// copies that used to define their own MyInt. A benchmark that additionally
139+
// wants the "trivial destructor after move" optimization can still specialize
140+
// boost::has_trivial_destructor_after_move<MyInt> in its own translation unit.
141+
///////////////////////////////////////////////////////////////////////////////
142+
class MyInt
143+
{
144+
int int_;
145+
146+
public:
147+
MyInt(int i = 0)
148+
: int_(i)
149+
{}
150+
151+
MyInt(const MyInt &other)
152+
: int_(other.int_)
153+
{}
154+
155+
MyInt & operator=(const MyInt &other)
156+
{
157+
int_ = other.int_;
158+
return *this;
159+
}
160+
161+
~MyInt()
162+
{
163+
int_ = 0;
164+
}
165+
166+
int int_value() const { return int_; }
167+
168+
friend bool operator==(const MyInt& a, const MyInt& b) { return a.int_ == b.int_; }
169+
friend bool operator!=(const MyInt& a, const MyInt& b) { return a.int_ != b.int_; }
170+
friend bool operator< (const MyInt& a, const MyInt& b) { return a.int_ < b.int_; }
171+
friend bool operator> (const MyInt& a, const MyInt& b) { return a.int_ > b.int_; }
172+
friend bool operator<=(const MyInt& a, const MyInt& b) { return a.int_ <= b.int_; }
173+
friend bool operator>=(const MyInt& a, const MyInt& b) { return a.int_ >= b.int_; }
174+
};
175+
176+
//Benchmark element. The NonTrivial boolean (chosen by the caller, true by
177+
//default) selects between two layouts of identical size:
178+
// - NonTrivial == true: a move-only element whose user-defined special members
179+
// do measurable work (memset/memcpy of the payload, kept alive by a compiler
180+
// barrier). It uses Boost.Move so the definition is also valid in C++03.
181+
// - NonTrivial == false: a trivially copyable element carrying only the payload.
182+
template<std::size_t Size, bool NonTrivial = true>
183+
struct element_t;
184+
185+
template<std::size_t Size>
186+
struct element_t<Size, true>
187+
{
188+
BOOST_MOVABLE_BUT_NOT_COPYABLE(element_t)
189+
190+
public:
191+
element_t(int n_) : n(n_)
192+
{
193+
std::memset(payload, 0, sizeof(payload));
194+
clobber(); //The barrier keeps previous writes as real work.
195+
}
196+
197+
~element_t()
198+
{
199+
std::memset(payload, 0, sizeof(payload));
200+
clobber(); //The barrier keeps previous writes as real work.
201+
}
202+
203+
element_t(BOOST_RV_REF(element_t) x) : n(x.n)
204+
{
205+
std::memcpy(payload, x.payload, sizeof(payload));
206+
std::memset(x.payload, 0, sizeof(payload));
207+
clobber(); //The barrier keeps previous writes as real work.
208+
}
209+
210+
element_t& operator=(BOOST_RV_REF(element_t) x)
211+
{
212+
n = x.n;
213+
std::memcpy(payload, x.payload, sizeof(payload));
214+
std::memset(x.payload, 0, sizeof(payload));
215+
clobber(); //The barrier keeps previous writes as real work.
216+
return *this;
217+
}
218+
219+
operator int() const { return n; }
220+
221+
int n;
222+
char payload[Size - sizeof(int)];
223+
};
224+
225+
template<std::size_t Size>
226+
struct element_t<Size, false>
227+
{
228+
element_t(int n_) : n(n_)
229+
{}
230+
231+
operator int() const { return n; }
232+
233+
int n;
234+
char payload[Size - sizeof(int)];
235+
};
236+
127237
#endif //BOOST_CONTAINER_BENCH_UTILS_HPP

bench/bench_vector.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,5 +35,6 @@ void run_containers(runner<IntType, Operation>& r)
3535
int main()
3636
{
3737
test_vectors<int>();
38+
test_vectors<MyInt>();
3839
return 0;
3940
}

0 commit comments

Comments
 (0)