////////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2025-2026. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/container for documentation. // ////////////////////////////////////////////////////////////////////////////// #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "../bench/bench_utils.hpp" namespace bc = boost::container; ////////////////////////////////////////////////////////////////////////////// // Value types ////////////////////////////////////////////////////////////////////////////// class MyInt { int int_; public: inline explicit MyInt(int i = 0) : int_(i) {} inline MyInt(const MyInt &other) : int_(other.int_) {} inline MyInt & operator=(const MyInt &other) { int_ = other.int_; return *this; } inline ~MyInt() { int_ = 0; } inline int int_value() const { return int_; } friend inline bool operator==(const MyInt& a, const MyInt& b) { return a.int_ == b.int_; } friend inline bool operator!=(const MyInt& a, const MyInt& b) { return a.int_ != b.int_; } friend inline bool operator<(const MyInt& a, const MyInt& b) { return a.int_ < b.int_; } friend inline bool operator>(const MyInt& a, const MyInt& b) { return a.int_ > b.int_; } }; class MyFatInt { int int0_; int int1_; int int2_; int int3_; int int4_; int int5_; int int6_; int int7_; public: inline explicit MyFatInt(int i = 0) : int0_(i++) , int1_(i++) , int2_(i++) , int3_(i++) , int4_(i++) , int5_(i++) , int6_(i++) , int7_(i++) {} inline MyFatInt(const MyFatInt &other) : int0_(other.int0_) , int1_(other.int1_) , int2_(other.int2_) , int3_(other.int3_) , int4_(other.int4_) , int5_(other.int5_) , int6_(other.int6_) , int7_(other.int7_) {} inline MyFatInt & operator=(const MyFatInt &other) { int0_ = other.int0_; int1_ = other.int1_; int2_ = other.int2_; int3_ = other.int3_; int4_ = other.int4_; int5_ = other.int5_; int6_ = other.int6_; int7_ = other.int7_; return *this; } inline ~MyFatInt() { int0_ = 0; int1_ = 0; int2_ = 0; int3_ = 0; int4_ = 0; int5_ = 0; int6_ = 0; int7_ = 0; } inline int int_value() const { return int0_; } friend inline bool operator==(const MyFatInt& a, const MyFatInt& b) { return a.int0_ == b.int0_; } friend inline bool operator!=(const MyFatInt& a, const MyFatInt& b) { return a.int0_ != b.int0_; } friend inline bool operator<(const MyFatInt& a, const MyFatInt& b) { return a.int0_ < b.int0_; } }; inline int int_value(int x) { return x; } inline int int_value(const MyInt& x) { return x.int_value(); } inline int int_value(const MyFatInt& x) { return x.int_value(); } ////////////////////////////////////////////////////////////////////////////// // Functors ////////////////////////////////////////////////////////////////////////////// template struct add_one { T operator()(const T& x) const { return T(int_value(x) + 1); } }; template struct is_odd { bool operator()(const T& x) const { return (int_value(x) & 1) != 0; } }; template struct summer { int sum; summer() : sum(0) {} void operator()(const T& x) { sum = static_cast((static_cast(sum) + static_cast(int_value(x)))); } }; template struct is_negative { bool operator()(const T& x) const { return int_value(x) < 0; } }; template struct is_zero_or_positive { bool operator()(const T& x) const { return int_value(x) >= 0; } }; template struct counter { int n; counter() : n(0) {} T operator()() { return T(n++); } }; template class equal_to_ref { typedef T value_type; const value_type &t_; public: BOOST_CONTAINER_FORCEINLINE explicit equal_to_ref(const value_type &t) : t_(t) {} template BOOST_CONTAINER_FORCEINLINE bool operator()(const U &t)const { return t_ == t; } }; template class less_than_ref { typedef T value_type; const value_type& t_; public: BOOST_CONTAINER_FORCEINLINE explicit less_than_ref(const value_type& t) : t_(t) { } template BOOST_CONTAINER_FORCEINLINE bool operator()(const U& t)const { return t < t_; } }; template class less_and_greater_ref { typedef T value_type; const value_type& l_; const value_type& g_; public: BOOST_CONTAINER_FORCEINLINE explicit less_and_greater_ref(const value_type& l, const value_type& g) : l_(l), g_(g) { } template BOOST_CONTAINER_FORCEINLINE bool operator()(const U& t)const { return t < l_ || t > g_ ; } }; template class unequal_to_ref { typedef T value_type; const value_type &t_; public: BOOST_CONTAINER_FORCEINLINE explicit unequal_to_ref(const value_type &t) : t_(t) {} template BOOST_CONTAINER_FORCEINLINE bool operator()(const U &t)const { return t_ != t; } }; ////////////////////////////////////////////////////////////////////////////// // C++03 fallbacks for C++11-only functions ////////////////////////////////////////////////////////////////////////////// namespace bench_detail { #if BOOST_CXX_VERSION < 201103L template bool all_of(InIt first, InIt last, Pred pred) { for (; first != last; ++first) if (!pred(*first)) return false; return true; } template bool any_of(InIt first, InIt last, Pred pred) { for (; first != last; ++first) if (pred(*first)) return true; return false; } template bool none_of(InIt first, InIt last, Pred pred) { for (; first != last; ++first) if (pred(*first)) return false; return true; } template inline InpIter find_if_not(InpIter first, Sent last, Pred pred) { return std::find_if(first, last, boost::container::not_pred(pred)); } template OutIt copy_if(InIt first, InIt last, OutIt d_first, Pred pred) { for (; first != last; ++first) if (pred(*first)) *d_first++ = *first; return d_first; } template OutIt copy_n(InIt first, Size count, OutIt result) { for (Size i = 0; i < count; ++i, ++first, ++result) *result = *first; return result; } template bool is_sorted(FwdIt first, FwdIt last) { if (first == last) return true; FwdIt next = first; for (++next; next != last; first = next, ++next) if (*next < *first) return false; return true; } template FwdIt is_sorted_until(FwdIt first, FwdIt last) { if (first == last) return last; FwdIt next = first; for (++next; next != last; first = next, ++next) if (*next < *first) return next; return last; } template bool is_partitioned(InIt first, InIt last, Pred pred) { for (; first != last; ++first) if (!pred(*first)) break; for (; first != last; ++first) if (pred(*first)) return false; return true; } template std::pair partition_copy(InIt first, InIt last, OutIt1 out_true, OutIt2 out_false, Pred pred) { for (; first != last; ++first) { if (pred(*first)) *out_true++ = *first; else *out_false++ = *first; } return std::pair(out_true, out_false); } template FwdIt partition_point(FwdIt first, FwdIt last, Pred pred) { for (; first != last; ++first) if (!pred(*first)) return first; return last; } #else using std::all_of; using std::any_of; using std::none_of; using std::find_if_not; using std::copy_if; using std::copy_n; using std::is_sorted; using std::is_sorted_until; using std::is_partitioned; using std::partition_copy; using std::partition_point; #endif template BidirIt find_last_dispatch(BidirIt first, BidirIt last, const T& val, std::bidirectional_iterator_tag) { BidirIt it = last; while (it != first) { --it; if (*it == val) return it; } return last; } template FwdIt find_last_dispatch(FwdIt first, FwdIt last, const T& val, std::forward_iterator_tag) { FwdIt result = last; for (; first != last; ++first) if (*first == val) result = first; return result; } template BOOST_CONTAINER_FORCEINLINE It find_last(It first, It last, const T& val) { typedef typename std::iterator_traits::iterator_category cat; return find_last_dispatch(first, last, val, cat()); } template BidirIt find_last_if_dispatch(BidirIt first, BidirIt last, Pred pred, std::bidirectional_iterator_tag) { BidirIt it = last; while (it != first) { --it; if (pred(*it)) return it; } return last; } template FwdIt find_last_if_dispatch(FwdIt first, FwdIt last, Pred pred, std::forward_iterator_tag) { FwdIt result = last; for (; first != last; ++first) if (pred(*first)) result = first; return result; } template BOOST_CONTAINER_FORCEINLINE It find_last_if(It first, It last, Pred pred) { typedef typename std::iterator_traits::iterator_category cat; return find_last_if_dispatch(first, last, pred, cat()); } template BidirIt find_last_if_not_dispatch(BidirIt first, BidirIt last, Pred pred, std::bidirectional_iterator_tag) { BidirIt it = last; while (it != first) { --it; if (!pred(*it)) return it; } return last; } template FwdIt find_last_if_not_dispatch(FwdIt first, FwdIt last, Pred pred, std::forward_iterator_tag) { FwdIt result = last; for (; first != last; ++first) if (!pred(*first)) result = first; return result; } template BOOST_CONTAINER_FORCEINLINE It find_last_if_not(It first, It last, Pred pred) { typedef typename std::iterator_traits::iterator_category cat; return find_last_if_not_dispatch(first, last, pred, cat()); } //Not benchmarked: //inplace_merge //not implemented (c++03) //find_end //find_first_of //adjacent_find //copy_backward //move //move_backward //transform //replace_copy //replace_copy_if //unique //unique_copy //rotate //rotate_copy //max_element //min_element //minmax_element //nth_element //includes //set_union //lexicographical_compare // -- sorting -- //sort (random-access non-implementable?) //stable_sort (random-access non-implementable?) //partial_sort (random-access non-implementable?) //partial_sort_copy(random-access non-implementable?) // -- binary search -- //lower_bound (binary/random-access non-implementable?) //upper_bound (binary/random-access non-implementable?) //equal_range (binary/random-access non-implementable?) //binary_search (binary/random-access non-implementable?) // -- heap -- //push_heap (binary/random-access non-implementable?) //pop_heap (binary/random-access non-implementable?) //make_heap (binary/random-access non-implementable?) //sort_heap (binary/random-access non-implementable?) // -- permutation -- //next_permutation //prev_permutation //is_permutation // -- numeric -- //iota //accumulate //inner_product //adjacent_difference //partial_sum //not implemented (c++11): //move //move_backward //shuffle (random-access non-implementable?) //is_heap (random-access non-implementable?) //is_heap_until (random-access non-implementable?) //not implemented (c++14) //mismatch with two full ranges //equal with two full ranges //not implemented (c++17) //for_each_n //random_shuffle (random-access non-implementable?) //sample (random-access non-implementable?) //reduce //exclusive_scan //inclusive_scan //transform_reduce //transform_exclusive_scan //transform_inclusive_scan //not implemented (c++20) //shift_left //shift_right //lexicographical_compare_three_way //range-based? //contains //contains_subrange //starts_with //ends_with //fold_left //fold_left_first //fold_right //fold_right_last //fold_left_with_iter //fold_left_first_with_iter //generate_random } // namespace bench_detail ////////////////////////////////////////////////////////////////////////////// // Fill helpers ////////////////////////////////////////////////////////////////////////////// template void fill_test_data(C& c, std::size_t n) { typedef typename C::value_type VT; for (std::size_t i = 0; i < n; ++i) c.push_back(VT(static_cast(i))); } template void fill_test_data(bc::nest& c, std::size_t n) { for (std::size_t i = 0; i < n; ++i) c.insert(T(static_cast(i))); } ////////////////////////////////////////////////////////////////////////////// // Benchmark helpers ////////////////////////////////////////////////////////////////////////////// inline double calc_ns_per_elem(boost::move_detail::nanosecond_type ns, std::size_t iters, std::size_t elems) { return double(ns) / double(iters * elems); } inline void print_subheader() { std::cout << std::left << std::setw(32) << "< algo >" << std::right << std::setw(20) << "< speedup >" << std::right << std::setw(20) << "< std ns/item >" << std::right << std::setw(20) << "< seg ns/item >" << '\n'; } struct geomean_accumulator { double log_sum; int count; void reset() { log_sum = 0.0; count = 0; } void add(double ratio) { if(ratio > 0.0) { log_sum += std::log(ratio); ++count; } } double result() const { return count > 0 ? std::exp(log_sum / count) : 0.0; } } g_geomean = { 0.0, 0 }; inline void print_ratio(const char* algo, const char*, double std_ns, double seg_ns) { double ratio = (seg_ns > 0.0) ? std_ns / seg_ns : 0.0; g_geomean.add(ratio); std::cout << std::left << std::setw(32) << algo << std::right << std::setw(20) << std::fixed << std::setprecision(2) << ((ratio < 1.0) ? "! " : "") << ratio << 'x' << std::right << std::setw(20) << std::fixed << std::setprecision(3) << std_ns << std::right << std::setw(20) << std::fixed << std::setprecision(3) << seg_ns << '\n'; } ////////////////////////////////////////////////////////////////////////////// // Individual benchmarks ////////////////////////////////////////////////////////////////////////////// template void bench_all_of(const C &c, std::size_t iters, const char* cname, Pred pred, const char* label) { int result = 0; cpu_timer t1; { std::size_t n_ = (iters + 7) / 8; t1.resume(); switch (iters % 8) { case 0: do { { clobber(); result = bench_detail::all_of(c.begin(), c.end(), pred) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 7: { clobber(); result = bench_detail::all_of(c.begin(), c.end(), pred) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 6: { clobber(); result = bench_detail::all_of(c.begin(), c.end(), pred) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 5: { clobber(); result = bench_detail::all_of(c.begin(), c.end(), pred) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 4: { clobber(); result = bench_detail::all_of(c.begin(), c.end(), pred) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 3: { clobber(); result = bench_detail::all_of(c.begin(), c.end(), pred) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 2: { clobber(); result = bench_detail::all_of(c.begin(), c.end(), pred) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 1: { clobber(); result = bench_detail::all_of(c.begin(), c.end(), pred) ? 1 : 0; escape(&result); } if (BOOST_UNLIKELY(--n_ == 0)) { t1.stop(); break; } } while (true); } } cpu_timer t2; { std::size_t n_ = (iters + 7) / 8; t2.resume(); switch (iters % 8) { case 0: do { { clobber(); result = bc::segmented_all_of(c.begin(), c.end(), pred) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 7: { clobber(); result = bc::segmented_all_of(c.begin(), c.end(), pred) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 6: { clobber(); result = bc::segmented_all_of(c.begin(), c.end(), pred) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 5: { clobber(); result = bc::segmented_all_of(c.begin(), c.end(), pred) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 4: { clobber(); result = bc::segmented_all_of(c.begin(), c.end(), pred) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 3: { clobber(); result = bc::segmented_all_of(c.begin(), c.end(), pred) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 2: { clobber(); result = bc::segmented_all_of(c.begin(), c.end(), pred) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 1: { clobber(); result = bc::segmented_all_of(c.begin(), c.end(), pred) ? 1 : 0; escape(&result); } if (BOOST_UNLIKELY(--n_ == 0)) { t2.stop(); break; } } while (true); } } double r1 = calc_ns_per_elem(t1.elapsed().wall, iters, c.size()); double r2 = calc_ns_per_elem(t2.elapsed().wall, iters, c.size()); print_ratio(label, cname, r1, r2); } template void bench_any_of(const C &c, std::size_t iters, const char* cname, Pred pred, const char* label) { int result = 0; cpu_timer t1; { std::size_t n_ = (iters + 7) / 8; t1.resume(); switch (iters % 8) { case 0: do { { clobber(); result = bench_detail::any_of(c.begin(), c.end(), pred) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 7: { clobber(); result = bench_detail::any_of(c.begin(), c.end(), pred) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 6: { clobber(); result = bench_detail::any_of(c.begin(), c.end(), pred) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 5: { clobber(); result = bench_detail::any_of(c.begin(), c.end(), pred) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 4: { clobber(); result = bench_detail::any_of(c.begin(), c.end(), pred) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 3: { clobber(); result = bench_detail::any_of(c.begin(), c.end(), pred) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 2: { clobber(); result = bench_detail::any_of(c.begin(), c.end(), pred) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 1: { clobber(); result = bench_detail::any_of(c.begin(), c.end(), pred) ? 1 : 0; escape(&result); } if (BOOST_UNLIKELY(--n_ == 0)) { t1.stop(); break; } } while (true); } } cpu_timer t2; { std::size_t n_ = (iters + 7) / 8; t2.resume(); switch (iters % 8) { case 0: do { { clobber(); result = bc::segmented_any_of(c.begin(), c.end(), pred) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 7: { clobber(); result = bc::segmented_any_of(c.begin(), c.end(), pred) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 6: { clobber(); result = bc::segmented_any_of(c.begin(), c.end(), pred) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 5: { clobber(); result = bc::segmented_any_of(c.begin(), c.end(), pred) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 4: { clobber(); result = bc::segmented_any_of(c.begin(), c.end(), pred) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 3: { clobber(); result = bc::segmented_any_of(c.begin(), c.end(), pred) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 2: { clobber(); result = bc::segmented_any_of(c.begin(), c.end(), pred) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 1: { clobber(); result = bc::segmented_any_of(c.begin(), c.end(), pred) ? 1 : 0; escape(&result); } if (BOOST_UNLIKELY(--n_ == 0)) { t2.stop(); break; } } while (true); } } double r1 = calc_ns_per_elem(t1.elapsed().wall, iters, c.size()); double r2 = calc_ns_per_elem(t2.elapsed().wall, iters, c.size()); print_ratio(label, cname, r1, r2); } template void bench_none_of(const C &c, std::size_t iters, const char* cname, Pred pred, const char* label) { int result = 0; cpu_timer t1; { std::size_t n_ = (iters + 7) / 8; t1.resume(); switch (iters % 8) { case 0: do { { clobber(); result = bench_detail::none_of(c.begin(), c.end(), pred) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 7: { clobber(); result = bench_detail::none_of(c.begin(), c.end(), pred) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 6: { clobber(); result = bench_detail::none_of(c.begin(), c.end(), pred) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 5: { clobber(); result = bench_detail::none_of(c.begin(), c.end(), pred) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 4: { clobber(); result = bench_detail::none_of(c.begin(), c.end(), pred) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 3: { clobber(); result = bench_detail::none_of(c.begin(), c.end(), pred) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 2: { clobber(); result = bench_detail::none_of(c.begin(), c.end(), pred) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 1: { clobber(); result = bench_detail::none_of(c.begin(), c.end(), pred) ? 1 : 0; escape(&result); } if (BOOST_UNLIKELY(--n_ == 0)) { t1.stop(); break; } } while (true); } } cpu_timer t2; { std::size_t n_ = (iters + 7) / 8; t2.resume(); switch (iters % 8) { case 0: do { { clobber(); result = bc::segmented_none_of(c.begin(), c.end(), pred) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 7: { clobber(); result = bc::segmented_none_of(c.begin(), c.end(), pred) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 6: { clobber(); result = bc::segmented_none_of(c.begin(), c.end(), pred) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 5: { clobber(); result = bc::segmented_none_of(c.begin(), c.end(), pred) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 4: { clobber(); result = bc::segmented_none_of(c.begin(), c.end(), pred) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 3: { clobber(); result = bc::segmented_none_of(c.begin(), c.end(), pred) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 2: { clobber(); result = bc::segmented_none_of(c.begin(), c.end(), pred) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 1: { clobber(); result = bc::segmented_none_of(c.begin(), c.end(), pred) ? 1 : 0; escape(&result); } if (BOOST_UNLIKELY(--n_ == 0)) { t2.stop(); break; } } while (true); } } double r1 = calc_ns_per_elem(t1.elapsed().wall, iters, c.size()); double r2 = calc_ns_per_elem(t2.elapsed().wall, iters, c.size()); print_ratio(label, cname, r1, r2); } template void bench_for_each(const C &c, std::size_t iters, const char* cname) { typedef typename C::value_type VT; int result = 0; cpu_timer t1; { std::size_t n_ = (iters + 7) / 8; t1.resume(); switch (iters % 8) { case 0: do { { summer s; clobber(); s = std::for_each(c.begin(), c.end(), s); result = s.sum; escape(&result); } BOOST_FALLTHROUGH; case 7: { summer s; clobber(); s = std::for_each(c.begin(), c.end(), s); result = s.sum; escape(&result); } BOOST_FALLTHROUGH; case 6: { summer s; clobber(); s = std::for_each(c.begin(), c.end(), s); result = s.sum; escape(&result); } BOOST_FALLTHROUGH; case 5: { summer s; clobber(); s = std::for_each(c.begin(), c.end(), s); result = s.sum; escape(&result); } BOOST_FALLTHROUGH; case 4: { summer s; clobber(); s = std::for_each(c.begin(), c.end(), s); result = s.sum; escape(&result); } BOOST_FALLTHROUGH; case 3: { summer s; clobber(); s = std::for_each(c.begin(), c.end(), s); result = s.sum; escape(&result); } BOOST_FALLTHROUGH; case 2: { summer s; clobber(); s = std::for_each(c.begin(), c.end(), s); result = s.sum; escape(&result); } BOOST_FALLTHROUGH; case 1: { summer s; clobber(); s = std::for_each(c.begin(), c.end(), s); result = s.sum; escape(&result); } if (BOOST_UNLIKELY(--n_ == 0)) { t1.stop(); break; } } while (true); } } cpu_timer t2; { std::size_t n_ = (iters + 7) / 8; t2.resume(); switch (iters % 8) { case 0: do { { summer s; clobber(); s = bc::segmented_for_each(c.begin(), c.end(), s); result = s.sum; escape(&result); } BOOST_FALLTHROUGH; case 7: { summer s; clobber(); s = bc::segmented_for_each(c.begin(), c.end(), s); result = s.sum; escape(&result); } BOOST_FALLTHROUGH; case 6: { summer s; clobber(); s = bc::segmented_for_each(c.begin(), c.end(), s); result = s.sum; escape(&result); } BOOST_FALLTHROUGH; case 5: { summer s; clobber(); s = bc::segmented_for_each(c.begin(), c.end(), s); result = s.sum; escape(&result); } BOOST_FALLTHROUGH; case 4: { summer s; clobber(); s = bc::segmented_for_each(c.begin(), c.end(), s); result = s.sum; escape(&result); } BOOST_FALLTHROUGH; case 3: { summer s; clobber(); s = bc::segmented_for_each(c.begin(), c.end(), s); result = s.sum; escape(&result); } BOOST_FALLTHROUGH; case 2: { summer s; clobber(); s = bc::segmented_for_each(c.begin(), c.end(), s); result = s.sum; escape(&result); } BOOST_FALLTHROUGH; case 1: { summer s; clobber(); s = bc::segmented_for_each(c.begin(), c.end(), s); result = s.sum; escape(&result); } if (BOOST_UNLIKELY(--n_ == 0)) { t2.stop(); break; } } while (true); } } double r1 = calc_ns_per_elem(t1.elapsed().wall, iters, c.size()); double r2 = calc_ns_per_elem(t2.elapsed().wall, iters, c.size()); print_ratio("for_each", cname, r1, r2); } template void bench_copy(const C &c, std::size_t iters, const char* cname, const char* label) { typedef typename C::value_type VT; typedef typename boost::move_detail::if_c, boost::container::vector >::type out_t; out_t out(c.size()); cpu_timer t1; { std::size_t n_ = (iters + 7) / 8; t1.resume(); switch (iters % 8) { case 0: do { { clobber(); std::copy(c.begin(), c.end(), out.begin()); escape(&out[0]); } BOOST_FALLTHROUGH; case 7: { clobber(); std::copy(c.begin(), c.end(), out.begin()); escape(&out[0]); } BOOST_FALLTHROUGH; case 6: { clobber(); std::copy(c.begin(), c.end(), out.begin()); escape(&out[0]); } BOOST_FALLTHROUGH; case 5: { clobber(); std::copy(c.begin(), c.end(), out.begin()); escape(&out[0]); } BOOST_FALLTHROUGH; case 4: { clobber(); std::copy(c.begin(), c.end(), out.begin()); escape(&out[0]); } BOOST_FALLTHROUGH; case 3: { clobber(); std::copy(c.begin(), c.end(), out.begin()); escape(&out[0]); } BOOST_FALLTHROUGH; case 2: { clobber(); std::copy(c.begin(), c.end(), out.begin()); escape(&out[0]); } BOOST_FALLTHROUGH; case 1: { clobber(); std::copy(c.begin(), c.end(), out.begin()); escape(&out[0]); } if (BOOST_UNLIKELY(--n_ == 0)) { t1.stop(); break; } } while (true); } } cpu_timer t2; { std::size_t n_ = (iters + 7) / 8; t2.resume(); switch (iters % 8) { case 0: do { { clobber(); bc::segmented_copy(c.begin(), c.end(), out.begin()); escape(&out[0]); } BOOST_FALLTHROUGH; case 7: { clobber(); bc::segmented_copy(c.begin(), c.end(), out.begin()); escape(&out[0]); } BOOST_FALLTHROUGH; case 6: { clobber(); bc::segmented_copy(c.begin(), c.end(), out.begin()); escape(&out[0]); } BOOST_FALLTHROUGH; case 5: { clobber(); bc::segmented_copy(c.begin(), c.end(), out.begin()); escape(&out[0]); } BOOST_FALLTHROUGH; case 4: { clobber(); bc::segmented_copy(c.begin(), c.end(), out.begin()); escape(&out[0]); } BOOST_FALLTHROUGH; case 3: { clobber(); bc::segmented_copy(c.begin(), c.end(), out.begin()); escape(&out[0]); } BOOST_FALLTHROUGH; case 2: { clobber(); bc::segmented_copy(c.begin(), c.end(), out.begin()); escape(&out[0]); } BOOST_FALLTHROUGH; case 1: { clobber(); bc::segmented_copy(c.begin(), c.end(), out.begin()); escape(&out[0]); } if (BOOST_UNLIKELY(--n_ == 0)) { t2.stop(); break; } } while (true); } } double r1 = calc_ns_per_elem(t1.elapsed().wall, iters, c.size()); double r2 = calc_ns_per_elem(t2.elapsed().wall, iters, c.size()); print_ratio(label, cname, r1, r2); } template void bench_copy_if(const C &c, std::size_t iters, const char* cname, Pred pred, const char* label) { typedef typename C::value_type VT; boost::container::vector out(c.size()); cpu_timer t1; { std::size_t n_ = (iters + 7) / 8; t1.resume(); switch (iters % 8) { case 0: do { { clobber(); bench_detail::copy_if(c.begin(), c.end(), out.begin(), pred); escape(&out[0]); } BOOST_FALLTHROUGH; case 7: { clobber(); bench_detail::copy_if(c.begin(), c.end(), out.begin(), pred); escape(&out[0]); } BOOST_FALLTHROUGH; case 6: { clobber(); bench_detail::copy_if(c.begin(), c.end(), out.begin(), pred); escape(&out[0]); } BOOST_FALLTHROUGH; case 5: { clobber(); bench_detail::copy_if(c.begin(), c.end(), out.begin(), pred); escape(&out[0]); } BOOST_FALLTHROUGH; case 4: { clobber(); bench_detail::copy_if(c.begin(), c.end(), out.begin(), pred); escape(&out[0]); } BOOST_FALLTHROUGH; case 3: { clobber(); bench_detail::copy_if(c.begin(), c.end(), out.begin(), pred); escape(&out[0]); } BOOST_FALLTHROUGH; case 2: { clobber(); bench_detail::copy_if(c.begin(), c.end(), out.begin(), pred); escape(&out[0]); } BOOST_FALLTHROUGH; case 1: { clobber(); bench_detail::copy_if(c.begin(), c.end(), out.begin(), pred); escape(&out[0]); } if (BOOST_UNLIKELY(--n_ == 0)) { t1.stop(); break; } } while (true); } } cpu_timer t2; { std::size_t n_ = (iters + 7) / 8; t2.resume(); switch (iters % 8) { case 0: do { { clobber(); bc::segmented_copy_if(c.begin(), c.end(), out.begin(), pred); escape(&out[0]); } BOOST_FALLTHROUGH; case 7: { clobber(); bc::segmented_copy_if(c.begin(), c.end(), out.begin(), pred); escape(&out[0]); } BOOST_FALLTHROUGH; case 6: { clobber(); bc::segmented_copy_if(c.begin(), c.end(), out.begin(), pred); escape(&out[0]); } BOOST_FALLTHROUGH; case 5: { clobber(); bc::segmented_copy_if(c.begin(), c.end(), out.begin(), pred); escape(&out[0]); } BOOST_FALLTHROUGH; case 4: { clobber(); bc::segmented_copy_if(c.begin(), c.end(), out.begin(), pred); escape(&out[0]); } BOOST_FALLTHROUGH; case 3: { clobber(); bc::segmented_copy_if(c.begin(), c.end(), out.begin(), pred); escape(&out[0]); } BOOST_FALLTHROUGH; case 2: { clobber(); bc::segmented_copy_if(c.begin(), c.end(), out.begin(), pred); escape(&out[0]); } BOOST_FALLTHROUGH; case 1: { clobber(); bc::segmented_copy_if(c.begin(), c.end(), out.begin(), pred); escape(&out[0]); } if (BOOST_UNLIKELY(--n_ == 0)) { t2.stop(); break; } } while (true); } } double r1 = calc_ns_per_elem(t1.elapsed().wall, iters, c.size()); double r2 = calc_ns_per_elem(t2.elapsed().wall, iters, c.size()); print_ratio(label, cname, r1, r2); } template void bench_fill(const C &c, std::size_t iters, const char* cname) { typedef typename C::value_type VT; VT val(42); C c2(c); cpu_timer t1; { std::size_t n_ = (iters + 7) / 8; t1.resume(); switch (iters % 8) { case 0: do { { clobber(); std::fill(c2.begin(), c2.end(), val); escape(&c2); } BOOST_FALLTHROUGH; case 7: { clobber(); std::fill(c2.begin(), c2.end(), val); escape(&c2); } BOOST_FALLTHROUGH; case 6: { clobber(); std::fill(c2.begin(), c2.end(), val); escape(&c2); } BOOST_FALLTHROUGH; case 5: { clobber(); std::fill(c2.begin(), c2.end(), val); escape(&c2); } BOOST_FALLTHROUGH; case 4: { clobber(); std::fill(c2.begin(), c2.end(), val); escape(&c2); } BOOST_FALLTHROUGH; case 3: { clobber(); std::fill(c2.begin(), c2.end(), val); escape(&c2); } BOOST_FALLTHROUGH; case 2: { clobber(); std::fill(c2.begin(), c2.end(), val); escape(&c2); } BOOST_FALLTHROUGH; case 1: { clobber(); std::fill(c2.begin(), c2.end(), val); escape(&c2); } if (BOOST_UNLIKELY(--n_ == 0)) { t1.stop(); break; } } while (true); } } cpu_timer t2; { std::size_t n_ = (iters + 7) / 8; t2.resume(); switch (iters % 8) { case 0: do { { clobber(); bc::segmented_fill(c2.begin(), c2.end(), val); escape(&c2); } BOOST_FALLTHROUGH; case 7: { clobber(); bc::segmented_fill(c2.begin(), c2.end(), val); escape(&c2); } BOOST_FALLTHROUGH; case 6: { clobber(); bc::segmented_fill(c2.begin(), c2.end(), val); escape(&c2); } BOOST_FALLTHROUGH; case 5: { clobber(); bc::segmented_fill(c2.begin(), c2.end(), val); escape(&c2); } BOOST_FALLTHROUGH; case 4: { clobber(); bc::segmented_fill(c2.begin(), c2.end(), val); escape(&c2); } BOOST_FALLTHROUGH; case 3: { clobber(); bc::segmented_fill(c2.begin(), c2.end(), val); escape(&c2); } BOOST_FALLTHROUGH; case 2: { clobber(); bc::segmented_fill(c2.begin(), c2.end(), val); escape(&c2); } BOOST_FALLTHROUGH; case 1: { clobber(); bc::segmented_fill(c2.begin(), c2.end(), val); escape(&c2); } if (BOOST_UNLIKELY(--n_ == 0)) { t2.stop(); break; } } while (true); } } double r1 = calc_ns_per_elem(t1.elapsed().wall, iters, c.size()); double r2 = calc_ns_per_elem(t2.elapsed().wall, iters, c.size()); print_ratio("fill", cname, r1, r2); } template void bench_count(const C &c, std::size_t iters, const char* cname, const typename C::value_type& val, const char* label) { int result = 0; cpu_timer t1; { std::size_t n_ = (iters + 7) / 8; t1.resume(); switch (iters % 8) { case 0: do { { clobber(); result = static_cast(std::count(c.begin(), c.end(), val)); escape(&result); } BOOST_FALLTHROUGH; case 7: { clobber(); result = static_cast(std::count(c.begin(), c.end(), val)); escape(&result); } BOOST_FALLTHROUGH; case 6: { clobber(); result = static_cast(std::count(c.begin(), c.end(), val)); escape(&result); } BOOST_FALLTHROUGH; case 5: { clobber(); result = static_cast(std::count(c.begin(), c.end(), val)); escape(&result); } BOOST_FALLTHROUGH; case 4: { clobber(); result = static_cast(std::count(c.begin(), c.end(), val)); escape(&result); } BOOST_FALLTHROUGH; case 3: { clobber(); result = static_cast(std::count(c.begin(), c.end(), val)); escape(&result); } BOOST_FALLTHROUGH; case 2: { clobber(); result = static_cast(std::count(c.begin(), c.end(), val)); escape(&result); } BOOST_FALLTHROUGH; case 1: { clobber(); result = static_cast(std::count(c.begin(), c.end(), val)); escape(&result); } if (BOOST_UNLIKELY(--n_ == 0)) { t1.stop(); break; } } while (true); } } cpu_timer t2; { std::size_t n_ = (iters + 7) / 8; t2.resume(); switch (iters % 8) { case 0: do { { clobber(); result = static_cast(bc::segmented_count(c.begin(), c.end(), val)); escape(&result); } BOOST_FALLTHROUGH; case 7: { clobber(); result = static_cast(bc::segmented_count(c.begin(), c.end(), val)); escape(&result); } BOOST_FALLTHROUGH; case 6: { clobber(); result = static_cast(bc::segmented_count(c.begin(), c.end(), val)); escape(&result); } BOOST_FALLTHROUGH; case 5: { clobber(); result = static_cast(bc::segmented_count(c.begin(), c.end(), val)); escape(&result); } BOOST_FALLTHROUGH; case 4: { clobber(); result = static_cast(bc::segmented_count(c.begin(), c.end(), val)); escape(&result); } BOOST_FALLTHROUGH; case 3: { clobber(); result = static_cast(bc::segmented_count(c.begin(), c.end(), val)); escape(&result); } BOOST_FALLTHROUGH; case 2: { clobber(); result = static_cast(bc::segmented_count(c.begin(), c.end(), val)); escape(&result); } BOOST_FALLTHROUGH; case 1: { clobber(); result = static_cast(bc::segmented_count(c.begin(), c.end(), val)); escape(&result); } if (BOOST_UNLIKELY(--n_ == 0)) { t2.stop(); break; } } while (true); } } double r1 = calc_ns_per_elem(t1.elapsed().wall, iters, c.size()); double r2 = calc_ns_per_elem(t2.elapsed().wall, iters, c.size()); print_ratio(label, cname, r1, r2); } template void bench_count_if(const C &c, std::size_t iters, const char* cname, Pred pred, const char* label) { int result = 0; cpu_timer t1; { std::size_t n_ = (iters + 7) / 8; t1.resume(); switch (iters % 8) { case 0: do { { clobber(); result = static_cast(std::count_if(c.begin(), c.end(), pred)); escape(&result); } BOOST_FALLTHROUGH; case 7: { clobber(); result = static_cast(std::count_if(c.begin(), c.end(), pred)); escape(&result); } BOOST_FALLTHROUGH; case 6: { clobber(); result = static_cast(std::count_if(c.begin(), c.end(), pred)); escape(&result); } BOOST_FALLTHROUGH; case 5: { clobber(); result = static_cast(std::count_if(c.begin(), c.end(), pred)); escape(&result); } BOOST_FALLTHROUGH; case 4: { clobber(); result = static_cast(std::count_if(c.begin(), c.end(), pred)); escape(&result); } BOOST_FALLTHROUGH; case 3: { clobber(); result = static_cast(std::count_if(c.begin(), c.end(), pred)); escape(&result); } BOOST_FALLTHROUGH; case 2: { clobber(); result = static_cast(std::count_if(c.begin(), c.end(), pred)); escape(&result); } BOOST_FALLTHROUGH; case 1: { clobber(); result = static_cast(std::count_if(c.begin(), c.end(), pred)); escape(&result); } if (BOOST_UNLIKELY(--n_ == 0)) { t1.stop(); break; } } while (true); } } cpu_timer t2; { std::size_t n_ = (iters + 7) / 8; t2.resume(); switch (iters % 8) { case 0: do { { clobber(); result = static_cast(bc::segmented_count_if(c.begin(), c.end(), pred)); escape(&result); } BOOST_FALLTHROUGH; case 7: { clobber(); result = static_cast(bc::segmented_count_if(c.begin(), c.end(), pred)); escape(&result); } BOOST_FALLTHROUGH; case 6: { clobber(); result = static_cast(bc::segmented_count_if(c.begin(), c.end(), pred)); escape(&result); } BOOST_FALLTHROUGH; case 5: { clobber(); result = static_cast(bc::segmented_count_if(c.begin(), c.end(), pred)); escape(&result); } BOOST_FALLTHROUGH; case 4: { clobber(); result = static_cast(bc::segmented_count_if(c.begin(), c.end(), pred)); escape(&result); } BOOST_FALLTHROUGH; case 3: { clobber(); result = static_cast(bc::segmented_count_if(c.begin(), c.end(), pred)); escape(&result); } BOOST_FALLTHROUGH; case 2: { clobber(); result = static_cast(bc::segmented_count_if(c.begin(), c.end(), pred)); escape(&result); } BOOST_FALLTHROUGH; case 1: { clobber(); result = static_cast(bc::segmented_count_if(c.begin(), c.end(), pred)); escape(&result); } if (BOOST_UNLIKELY(--n_ == 0)) { t2.stop(); break; } } while (true); } } double r1 = calc_ns_per_elem(t1.elapsed().wall, iters, c.size()); double r2 = calc_ns_per_elem(t2.elapsed().wall, iters, c.size()); print_ratio(label, cname, r1, r2); } template void bench_find(const C &c, std::size_t iters, const char* cname, const typename C::value_type& val, const char* label) { typedef typename C::const_iterator cit_t; int result = 0; cpu_timer t1; { std::size_t n_ = (iters + 7) / 8; t1.resume(); switch (iters % 8) { case 0: do { { clobber(); cit_t it = std::find(c.begin(), c.end(), val); result = (it == c.end()) ? 0 : 1; escape(&result); } BOOST_FALLTHROUGH; case 7: { clobber(); cit_t it = std::find(c.begin(), c.end(), val); result = (it == c.end()) ? 0 : 1; escape(&result); } BOOST_FALLTHROUGH; case 6: { clobber(); cit_t it = std::find(c.begin(), c.end(), val); result = (it == c.end()) ? 0 : 1; escape(&result); } BOOST_FALLTHROUGH; case 5: { clobber(); cit_t it = std::find(c.begin(), c.end(), val); result = (it == c.end()) ? 0 : 1; escape(&result); } BOOST_FALLTHROUGH; case 4: { clobber(); cit_t it = std::find(c.begin(), c.end(), val); result = (it == c.end()) ? 0 : 1; escape(&result); } BOOST_FALLTHROUGH; case 3: { clobber(); cit_t it = std::find(c.begin(), c.end(), val); result = (it == c.end()) ? 0 : 1; escape(&result); } BOOST_FALLTHROUGH; case 2: { clobber(); cit_t it = std::find(c.begin(), c.end(), val); result = (it == c.end()) ? 0 : 1; escape(&result); } BOOST_FALLTHROUGH; case 1: { clobber(); cit_t it = std::find(c.begin(), c.end(), val); result = (it == c.end()) ? 0 : 1; escape(&result); } if (BOOST_UNLIKELY(--n_ == 0)) { t1.stop(); break; } } while (true); } } cpu_timer t2; { std::size_t n_ = (iters + 7) / 8; t2.resume(); switch (iters % 8) { case 0: do { { clobber(); cit_t it = bc::segmented_find(c.begin(), c.end(), val); result = (it == c.end()) ? 0 : 1; escape(&result); } BOOST_FALLTHROUGH; case 7: { clobber(); cit_t it = bc::segmented_find(c.begin(), c.end(), val); result = (it == c.end()) ? 0 : 1; escape(&result); } BOOST_FALLTHROUGH; case 6: { clobber(); cit_t it = bc::segmented_find(c.begin(), c.end(), val); result = (it == c.end()) ? 0 : 1; escape(&result); } BOOST_FALLTHROUGH; case 5: { clobber(); cit_t it = bc::segmented_find(c.begin(), c.end(), val); result = (it == c.end()) ? 0 : 1; escape(&result); } BOOST_FALLTHROUGH; case 4: { clobber(); cit_t it = bc::segmented_find(c.begin(), c.end(), val); result = (it == c.end()) ? 0 : 1; escape(&result); } BOOST_FALLTHROUGH; case 3: { clobber(); cit_t it = bc::segmented_find(c.begin(), c.end(), val); result = (it == c.end()) ? 0 : 1; escape(&result); } BOOST_FALLTHROUGH; case 2: { clobber(); cit_t it = bc::segmented_find(c.begin(), c.end(), val); result = (it == c.end()) ? 0 : 1; escape(&result); } BOOST_FALLTHROUGH; case 1: { clobber(); cit_t it = bc::segmented_find(c.begin(), c.end(), val); result = (it == c.end()) ? 0 : 1; escape(&result); } if (BOOST_UNLIKELY(--n_ == 0)) { t2.stop(); break; } } while (true); } } double r1 = calc_ns_per_elem(t1.elapsed().wall, iters, c.size()); double r2 = calc_ns_per_elem(t2.elapsed().wall, iters, c.size()); print_ratio(label, cname, r1, r2); } template void bench_find_if(const C &c, std::size_t iters, const char* cname, Pred pred, const char* label) { typedef typename C::const_iterator cit_t; int result = 0; cpu_timer t1; { std::size_t n_ = (iters + 7) / 8; t1.resume(); switch (iters % 8) { case 0: do { { clobber(); cit_t it = std::find_if(c.begin(), c.end(), pred); result = (it != c.end()) ? int_value(*it) : -1; escape(&result); } BOOST_FALLTHROUGH; case 7: { clobber(); cit_t it = std::find_if(c.begin(), c.end(), pred); result = (it != c.end()) ? int_value(*it) : -1; escape(&result); } BOOST_FALLTHROUGH; case 6: { clobber(); cit_t it = std::find_if(c.begin(), c.end(), pred); result = (it != c.end()) ? int_value(*it) : -1; escape(&result); } BOOST_FALLTHROUGH; case 5: { clobber(); cit_t it = std::find_if(c.begin(), c.end(), pred); result = (it != c.end()) ? int_value(*it) : -1; escape(&result); } BOOST_FALLTHROUGH; case 4: { clobber(); cit_t it = std::find_if(c.begin(), c.end(), pred); result = (it != c.end()) ? int_value(*it) : -1; escape(&result); } BOOST_FALLTHROUGH; case 3: { clobber(); cit_t it = std::find_if(c.begin(), c.end(), pred); result = (it != c.end()) ? int_value(*it) : -1; escape(&result); } BOOST_FALLTHROUGH; case 2: { clobber(); cit_t it = std::find_if(c.begin(), c.end(), pred); result = (it != c.end()) ? int_value(*it) : -1; escape(&result); } BOOST_FALLTHROUGH; case 1: { clobber(); cit_t it = std::find_if(c.begin(), c.end(), pred); result = (it != c.end()) ? int_value(*it) : -1; escape(&result); } if (BOOST_UNLIKELY(--n_ == 0)) { t1.stop(); break; } } while (true); } } cpu_timer t2; { std::size_t n_ = (iters + 7) / 8; t2.resume(); switch (iters % 8) { case 0: do { { clobber(); cit_t it = bc::segmented_find_if(c.begin(), c.end(), pred); result = (it != c.end()) ? int_value(*it) : -1; escape(&result); } BOOST_FALLTHROUGH; case 7: { clobber(); cit_t it = bc::segmented_find_if(c.begin(), c.end(), pred); result = (it != c.end()) ? int_value(*it) : -1; escape(&result); } BOOST_FALLTHROUGH; case 6: { clobber(); cit_t it = bc::segmented_find_if(c.begin(), c.end(), pred); result = (it != c.end()) ? int_value(*it) : -1; escape(&result); } BOOST_FALLTHROUGH; case 5: { clobber(); cit_t it = bc::segmented_find_if(c.begin(), c.end(), pred); result = (it != c.end()) ? int_value(*it) : -1; escape(&result); } BOOST_FALLTHROUGH; case 4: { clobber(); cit_t it = bc::segmented_find_if(c.begin(), c.end(), pred); result = (it != c.end()) ? int_value(*it) : -1; escape(&result); } BOOST_FALLTHROUGH; case 3: { clobber(); cit_t it = bc::segmented_find_if(c.begin(), c.end(), pred); result = (it != c.end()) ? int_value(*it) : -1; escape(&result); } BOOST_FALLTHROUGH; case 2: { clobber(); cit_t it = bc::segmented_find_if(c.begin(), c.end(), pred); result = (it != c.end()) ? int_value(*it) : -1; escape(&result); } BOOST_FALLTHROUGH; case 1: { clobber(); cit_t it = bc::segmented_find_if(c.begin(), c.end(), pred); result = (it != c.end()) ? int_value(*it) : -1; escape(&result); } if (BOOST_UNLIKELY(--n_ == 0)) { t2.stop(); break; } } while (true); } } double r1 = calc_ns_per_elem(t1.elapsed().wall, iters, c.size()); double r2 = calc_ns_per_elem(t2.elapsed().wall, iters, c.size()); print_ratio(label, cname, r1, r2); } template void bench_find_if_not(const C &c, std::size_t iters, const char* cname, Pred pred, const char* label) { typedef typename C::const_iterator cit_t; int result = 0; cpu_timer t1; { std::size_t n_ = (iters + 7) / 8; t1.resume(); switch (iters % 8) { case 0: do { { clobber(); cit_t it = bench_detail::find_if_not(c.begin(), c.end(), pred); result = (it != c.end()) ? int_value(*it) : -1; escape(&result); } BOOST_FALLTHROUGH; case 7: { clobber(); cit_t it = bench_detail::find_if_not(c.begin(), c.end(), pred); result = (it != c.end()) ? int_value(*it) : -1; escape(&result); } BOOST_FALLTHROUGH; case 6: { clobber(); cit_t it = bench_detail::find_if_not(c.begin(), c.end(), pred); result = (it != c.end()) ? int_value(*it) : -1; escape(&result); } BOOST_FALLTHROUGH; case 5: { clobber(); cit_t it = bench_detail::find_if_not(c.begin(), c.end(), pred); result = (it != c.end()) ? int_value(*it) : -1; escape(&result); } BOOST_FALLTHROUGH; case 4: { clobber(); cit_t it = bench_detail::find_if_not(c.begin(), c.end(), pred); result = (it != c.end()) ? int_value(*it) : -1; escape(&result); } BOOST_FALLTHROUGH; case 3: { clobber(); cit_t it = bench_detail::find_if_not(c.begin(), c.end(), pred); result = (it != c.end()) ? int_value(*it) : -1; escape(&result); } BOOST_FALLTHROUGH; case 2: { clobber(); cit_t it = bench_detail::find_if_not(c.begin(), c.end(), pred); result = (it != c.end()) ? int_value(*it) : -1; escape(&result); } BOOST_FALLTHROUGH; case 1: { clobber(); cit_t it = bench_detail::find_if_not(c.begin(), c.end(), pred); result = (it != c.end()) ? int_value(*it) : -1; escape(&result); } if (BOOST_UNLIKELY(--n_ == 0)) { t1.stop(); break; } } while (true); } } cpu_timer t2; { std::size_t n_ = (iters + 7) / 8; t2.resume(); switch (iters % 8) { case 0: do { { clobber(); cit_t it = bc::segmented_find_if_not(c.begin(), c.end(), pred); result = (it != c.end()) ? int_value(*it) : -1; escape(&result); } BOOST_FALLTHROUGH; case 7: { clobber(); cit_t it = bc::segmented_find_if_not(c.begin(), c.end(), pred); result = (it != c.end()) ? int_value(*it) : -1; escape(&result); } BOOST_FALLTHROUGH; case 6: { clobber(); cit_t it = bc::segmented_find_if_not(c.begin(), c.end(), pred); result = (it != c.end()) ? int_value(*it) : -1; escape(&result); } BOOST_FALLTHROUGH; case 5: { clobber(); cit_t it = bc::segmented_find_if_not(c.begin(), c.end(), pred); result = (it != c.end()) ? int_value(*it) : -1; escape(&result); } BOOST_FALLTHROUGH; case 4: { clobber(); cit_t it = bc::segmented_find_if_not(c.begin(), c.end(), pred); result = (it != c.end()) ? int_value(*it) : -1; escape(&result); } BOOST_FALLTHROUGH; case 3: { clobber(); cit_t it = bc::segmented_find_if_not(c.begin(), c.end(), pred); result = (it != c.end()) ? int_value(*it) : -1; escape(&result); } BOOST_FALLTHROUGH; case 2: { clobber(); cit_t it = bc::segmented_find_if_not(c.begin(), c.end(), pred); result = (it != c.end()) ? int_value(*it) : -1; escape(&result); } BOOST_FALLTHROUGH; case 1: { clobber(); cit_t it = bc::segmented_find_if_not(c.begin(), c.end(), pred); result = (it != c.end()) ? int_value(*it) : -1; escape(&result); } if (BOOST_UNLIKELY(--n_ == 0)) { t2.stop(); break; } } while (true); } } double r1 = calc_ns_per_elem(t1.elapsed().wall, iters, c.size()); double r2 = calc_ns_per_elem(t2.elapsed().wall, iters, c.size()); print_ratio(label, cname, r1, r2); } template void bench_find_last(const C &c, std::size_t iters, const char* cname, const typename C::value_type& val, const char* label) { typedef typename C::const_iterator cit_t; int result = 0; cpu_timer t1; { std::size_t n_ = (iters + 7) / 8; t1.resume(); switch (iters % 8) { case 0: do { { clobber(); cit_t it = bench_detail::find_last(c.begin(), c.end(), val); result = (it == c.end()) ? 0 : 1; escape(&result); } BOOST_FALLTHROUGH; case 7: { clobber(); cit_t it = bench_detail::find_last(c.begin(), c.end(), val); result = (it == c.end()) ? 0 : 1; escape(&result); } BOOST_FALLTHROUGH; case 6: { clobber(); cit_t it = bench_detail::find_last(c.begin(), c.end(), val); result = (it == c.end()) ? 0 : 1; escape(&result); } BOOST_FALLTHROUGH; case 5: { clobber(); cit_t it = bench_detail::find_last(c.begin(), c.end(), val); result = (it == c.end()) ? 0 : 1; escape(&result); } BOOST_FALLTHROUGH; case 4: { clobber(); cit_t it = bench_detail::find_last(c.begin(), c.end(), val); result = (it == c.end()) ? 0 : 1; escape(&result); } BOOST_FALLTHROUGH; case 3: { clobber(); cit_t it = bench_detail::find_last(c.begin(), c.end(), val); result = (it == c.end()) ? 0 : 1; escape(&result); } BOOST_FALLTHROUGH; case 2: { clobber(); cit_t it = bench_detail::find_last(c.begin(), c.end(), val); result = (it == c.end()) ? 0 : 1; escape(&result); } BOOST_FALLTHROUGH; case 1: { clobber(); cit_t it = bench_detail::find_last(c.begin(), c.end(), val); result = (it == c.end()) ? 0 : 1; escape(&result); } if (BOOST_UNLIKELY(--n_ == 0)) { t1.stop(); break; } } while (true); } } cpu_timer t2; { std::size_t n_ = (iters + 7) / 8; t2.resume(); switch (iters % 8) { case 0: do { { clobber(); cit_t it = bc::segmented_find_last(c.begin(), c.end(), val); result = (it == c.end()) ? 0 : 1; escape(&result); } BOOST_FALLTHROUGH; case 7: { clobber(); cit_t it = bc::segmented_find_last(c.begin(), c.end(), val); result = (it == c.end()) ? 0 : 1; escape(&result); } BOOST_FALLTHROUGH; case 6: { clobber(); cit_t it = bc::segmented_find_last(c.begin(), c.end(), val); result = (it == c.end()) ? 0 : 1; escape(&result); } BOOST_FALLTHROUGH; case 5: { clobber(); cit_t it = bc::segmented_find_last(c.begin(), c.end(), val); result = (it == c.end()) ? 0 : 1; escape(&result); } BOOST_FALLTHROUGH; case 4: { clobber(); cit_t it = bc::segmented_find_last(c.begin(), c.end(), val); result = (it == c.end()) ? 0 : 1; escape(&result); } BOOST_FALLTHROUGH; case 3: { clobber(); cit_t it = bc::segmented_find_last(c.begin(), c.end(), val); result = (it == c.end()) ? 0 : 1; escape(&result); } BOOST_FALLTHROUGH; case 2: { clobber(); cit_t it = bc::segmented_find_last(c.begin(), c.end(), val); result = (it == c.end()) ? 0 : 1; escape(&result); } BOOST_FALLTHROUGH; case 1: { clobber(); cit_t it = bc::segmented_find_last(c.begin(), c.end(), val); result = (it == c.end()) ? 0 : 1; escape(&result); } if (BOOST_UNLIKELY(--n_ == 0)) { t2.stop(); break; } } while (true); } } double r1 = calc_ns_per_elem(t1.elapsed().wall, iters, c.size()); double r2 = calc_ns_per_elem(t2.elapsed().wall, iters, c.size()); print_ratio(label, cname, r1, r2); } template void bench_find_last_if(const C &c, std::size_t iters, const char* cname, Pred pred, const char* label) { typedef typename C::const_iterator cit_t; int result = 0; cpu_timer t1; { std::size_t n_ = (iters + 7) / 8; t1.resume(); switch (iters % 8) { case 0: do { { clobber(); cit_t it = bench_detail::find_last_if(c.begin(), c.end(), pred); result = (it != c.end()) ? int_value(*it) : -1; escape(&result); } BOOST_FALLTHROUGH; case 7: { clobber(); cit_t it = bench_detail::find_last_if(c.begin(), c.end(), pred); result = (it != c.end()) ? int_value(*it) : -1; escape(&result); } BOOST_FALLTHROUGH; case 6: { clobber(); cit_t it = bench_detail::find_last_if(c.begin(), c.end(), pred); result = (it != c.end()) ? int_value(*it) : -1; escape(&result); } BOOST_FALLTHROUGH; case 5: { clobber(); cit_t it = bench_detail::find_last_if(c.begin(), c.end(), pred); result = (it != c.end()) ? int_value(*it) : -1; escape(&result); } BOOST_FALLTHROUGH; case 4: { clobber(); cit_t it = bench_detail::find_last_if(c.begin(), c.end(), pred); result = (it != c.end()) ? int_value(*it) : -1; escape(&result); } BOOST_FALLTHROUGH; case 3: { clobber(); cit_t it = bench_detail::find_last_if(c.begin(), c.end(), pred); result = (it != c.end()) ? int_value(*it) : -1; escape(&result); } BOOST_FALLTHROUGH; case 2: { clobber(); cit_t it = bench_detail::find_last_if(c.begin(), c.end(), pred); result = (it != c.end()) ? int_value(*it) : -1; escape(&result); } BOOST_FALLTHROUGH; case 1: { clobber(); cit_t it = bench_detail::find_last_if(c.begin(), c.end(), pred); result = (it != c.end()) ? int_value(*it) : -1; escape(&result); } if (BOOST_UNLIKELY(--n_ == 0)) { t1.stop(); break; } } while (true); } } cpu_timer t2; { std::size_t n_ = (iters + 7) / 8; t2.resume(); switch (iters % 8) { case 0: do { { clobber(); cit_t it = bc::segmented_find_last_if(c.begin(), c.end(), pred); result = (it != c.end()) ? int_value(*it) : -1; escape(&result); } BOOST_FALLTHROUGH; case 7: { clobber(); cit_t it = bc::segmented_find_last_if(c.begin(), c.end(), pred); result = (it != c.end()) ? int_value(*it) : -1; escape(&result); } BOOST_FALLTHROUGH; case 6: { clobber(); cit_t it = bc::segmented_find_last_if(c.begin(), c.end(), pred); result = (it != c.end()) ? int_value(*it) : -1; escape(&result); } BOOST_FALLTHROUGH; case 5: { clobber(); cit_t it = bc::segmented_find_last_if(c.begin(), c.end(), pred); result = (it != c.end()) ? int_value(*it) : -1; escape(&result); } BOOST_FALLTHROUGH; case 4: { clobber(); cit_t it = bc::segmented_find_last_if(c.begin(), c.end(), pred); result = (it != c.end()) ? int_value(*it) : -1; escape(&result); } BOOST_FALLTHROUGH; case 3: { clobber(); cit_t it = bc::segmented_find_last_if(c.begin(), c.end(), pred); result = (it != c.end()) ? int_value(*it) : -1; escape(&result); } BOOST_FALLTHROUGH; case 2: { clobber(); cit_t it = bc::segmented_find_last_if(c.begin(), c.end(), pred); result = (it != c.end()) ? int_value(*it) : -1; escape(&result); } BOOST_FALLTHROUGH; case 1: { clobber(); cit_t it = bc::segmented_find_last_if(c.begin(), c.end(), pred); result = (it != c.end()) ? int_value(*it) : -1; escape(&result); } if (BOOST_UNLIKELY(--n_ == 0)) { t2.stop(); break; } } while (true); } } double r1 = calc_ns_per_elem(t1.elapsed().wall, iters, c.size()); double r2 = calc_ns_per_elem(t2.elapsed().wall, iters, c.size()); print_ratio(label, cname, r1, r2); } template void bench_find_last_if_not(const C &c, std::size_t iters, const char* cname, Pred pred, const char* label) { typedef typename C::const_iterator cit_t; int result = 0; cpu_timer t1; { std::size_t n_ = (iters + 7) / 8; t1.resume(); switch (iters % 8) { case 0: do { { clobber(); cit_t it = bench_detail::find_last_if_not(c.begin(), c.end(), pred); result = (it != c.end()) ? int_value(*it) : -1; escape(&result); } BOOST_FALLTHROUGH; case 7: { clobber(); cit_t it = bench_detail::find_last_if_not(c.begin(), c.end(), pred); result = (it != c.end()) ? int_value(*it) : -1; escape(&result); } BOOST_FALLTHROUGH; case 6: { clobber(); cit_t it = bench_detail::find_last_if_not(c.begin(), c.end(), pred); result = (it != c.end()) ? int_value(*it) : -1; escape(&result); } BOOST_FALLTHROUGH; case 5: { clobber(); cit_t it = bench_detail::find_last_if_not(c.begin(), c.end(), pred); result = (it != c.end()) ? int_value(*it) : -1; escape(&result); } BOOST_FALLTHROUGH; case 4: { clobber(); cit_t it = bench_detail::find_last_if_not(c.begin(), c.end(), pred); result = (it != c.end()) ? int_value(*it) : -1; escape(&result); } BOOST_FALLTHROUGH; case 3: { clobber(); cit_t it = bench_detail::find_last_if_not(c.begin(), c.end(), pred); result = (it != c.end()) ? int_value(*it) : -1; escape(&result); } BOOST_FALLTHROUGH; case 2: { clobber(); cit_t it = bench_detail::find_last_if_not(c.begin(), c.end(), pred); result = (it != c.end()) ? int_value(*it) : -1; escape(&result); } BOOST_FALLTHROUGH; case 1: { clobber(); cit_t it = bench_detail::find_last_if_not(c.begin(), c.end(), pred); result = (it != c.end()) ? int_value(*it) : -1; escape(&result); } if (BOOST_UNLIKELY(--n_ == 0)) { t1.stop(); break; } } while (true); } } cpu_timer t2; { std::size_t n_ = (iters + 7) / 8; t2.resume(); switch (iters % 8) { case 0: do { { clobber(); cit_t it = bc::segmented_find_last_if_not(c.begin(), c.end(), pred); result = (it != c.end()) ? int_value(*it) : -1; escape(&result); } BOOST_FALLTHROUGH; case 7: { clobber(); cit_t it = bc::segmented_find_last_if_not(c.begin(), c.end(), pred); result = (it != c.end()) ? int_value(*it) : -1; escape(&result); } BOOST_FALLTHROUGH; case 6: { clobber(); cit_t it = bc::segmented_find_last_if_not(c.begin(), c.end(), pred); result = (it != c.end()) ? int_value(*it) : -1; escape(&result); } BOOST_FALLTHROUGH; case 5: { clobber(); cit_t it = bc::segmented_find_last_if_not(c.begin(), c.end(), pred); result = (it != c.end()) ? int_value(*it) : -1; escape(&result); } BOOST_FALLTHROUGH; case 4: { clobber(); cit_t it = bc::segmented_find_last_if_not(c.begin(), c.end(), pred); result = (it != c.end()) ? int_value(*it) : -1; escape(&result); } BOOST_FALLTHROUGH; case 3: { clobber(); cit_t it = bc::segmented_find_last_if_not(c.begin(), c.end(), pred); result = (it != c.end()) ? int_value(*it) : -1; escape(&result); } BOOST_FALLTHROUGH; case 2: { clobber(); cit_t it = bc::segmented_find_last_if_not(c.begin(), c.end(), pred); result = (it != c.end()) ? int_value(*it) : -1; escape(&result); } BOOST_FALLTHROUGH; case 1: { clobber(); cit_t it = bc::segmented_find_last_if_not(c.begin(), c.end(), pred); result = (it != c.end()) ? int_value(*it) : -1; escape(&result); } if (BOOST_UNLIKELY(--n_ == 0)) { t2.stop(); break; } } while (true); } } double r1 = calc_ns_per_elem(t1.elapsed().wall, iters, c.size()); double r2 = calc_ns_per_elem(t2.elapsed().wall, iters, c.size()); print_ratio(label, cname, r1, r2); } template void bench_equal(const C &c, const C &c2, std::size_t iters, const char* cname, const char* label) { int result = 0; cpu_timer t1; { std::size_t n_ = (iters + 7) / 8; t1.resume(); switch (iters % 8) { case 0: do { { clobber(); result = std::equal(c.begin(), c.end(), c2.begin()) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 7: { clobber(); result = std::equal(c.begin(), c.end(), c2.begin()) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 6: { clobber(); result = std::equal(c.begin(), c.end(), c2.begin()) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 5: { clobber(); result = std::equal(c.begin(), c.end(), c2.begin()) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 4: { clobber(); result = std::equal(c.begin(), c.end(), c2.begin()) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 3: { clobber(); result = std::equal(c.begin(), c.end(), c2.begin()) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 2: { clobber(); result = std::equal(c.begin(), c.end(), c2.begin()) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 1: { clobber(); result = std::equal(c.begin(), c.end(), c2.begin()) ? 1 : 0; escape(&result); } if (BOOST_UNLIKELY(--n_ == 0)) { t1.stop(); break; } } while (true); } } cpu_timer t2; { std::size_t n_ = (iters + 7) / 8; t2.resume(); switch (iters % 8) { case 0: do { { clobber(); result = bc::segmented_equal(c.begin(), c.end(), c2.begin()) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 7: { clobber(); result = bc::segmented_equal(c.begin(), c.end(), c2.begin()) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 6: { clobber(); result = bc::segmented_equal(c.begin(), c.end(), c2.begin()) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 5: { clobber(); result = bc::segmented_equal(c.begin(), c.end(), c2.begin()) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 4: { clobber(); result = bc::segmented_equal(c.begin(), c.end(), c2.begin()) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 3: { clobber(); result = bc::segmented_equal(c.begin(), c.end(), c2.begin()) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 2: { clobber(); result = bc::segmented_equal(c.begin(), c.end(), c2.begin()) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 1: { clobber(); result = bc::segmented_equal(c.begin(), c.end(), c2.begin()) ? 1 : 0; escape(&result); } if (BOOST_UNLIKELY(--n_ == 0)) { t2.stop(); break; } } while (true); } } double r1 = calc_ns_per_elem(t1.elapsed().wall, iters, c.size()); double r2 = calc_ns_per_elem(t2.elapsed().wall, iters, c.size()); print_ratio(label, cname, r1, r2); } template void bench_replace(const C &c, std::size_t iters, const char* cname, const typename C::value_type& old_val, const typename C::value_type& new_val, const char* label) { typedef const typename C::value_type* cptr; cptr pold_val = &old_val; cptr pnew_val = &new_val; cpu_timer t1; { C c2(c); std::size_t n_ = (iters + 7) / 8; t1.resume(); switch (iters % 8) { case 0: do { { clobber(); std::replace(c2.begin(), c2.end(), *pold_val, *pnew_val); escape(&c2); cptr pt(pold_val); pold_val = pnew_val; pnew_val = pt; } BOOST_FALLTHROUGH; case 7: { clobber(); std::replace(c2.begin(), c2.end(), *pold_val, *pnew_val); escape(&c2); cptr pt(pold_val); pold_val = pnew_val; pnew_val = pt; } BOOST_FALLTHROUGH; case 6: { clobber(); std::replace(c2.begin(), c2.end(), *pold_val, *pnew_val); escape(&c2); cptr pt(pold_val); pold_val = pnew_val; pnew_val = pt; } BOOST_FALLTHROUGH; case 5: { clobber(); std::replace(c2.begin(), c2.end(), *pold_val, *pnew_val); escape(&c2); cptr pt(pold_val); pold_val = pnew_val; pnew_val = pt; } BOOST_FALLTHROUGH; case 4: { clobber(); std::replace(c2.begin(), c2.end(), *pold_val, *pnew_val); escape(&c2); cptr pt(pold_val); pold_val = pnew_val; pnew_val = pt; } BOOST_FALLTHROUGH; case 3: { clobber(); std::replace(c2.begin(), c2.end(), *pold_val, *pnew_val); escape(&c2); cptr pt(pold_val); pold_val = pnew_val; pnew_val = pt; } BOOST_FALLTHROUGH; case 2: { clobber(); std::replace(c2.begin(), c2.end(), *pold_val, *pnew_val); escape(&c2); cptr pt(pold_val); pold_val = pnew_val; pnew_val = pt; } BOOST_FALLTHROUGH; case 1: { clobber(); std::replace(c2.begin(), c2.end(), *pold_val, *pnew_val); escape(&c2); cptr pt(pold_val); pold_val = pnew_val; pnew_val = pt; } if (BOOST_UNLIKELY(--n_ == 0)) { t1.stop(); break; } } while (true); } } pold_val = &old_val; pnew_val = &new_val; cpu_timer t2; { C c2(c); std::size_t n_ = (iters + 7) / 8; t2.resume(); switch (iters % 8) { case 0: do { { clobber(); bc::segmented_replace(c2.begin(), c2.end(), *pold_val, *pnew_val); escape(&c2); cptr pt(pold_val); pold_val = pnew_val; pnew_val = pt; } BOOST_FALLTHROUGH; case 7: { clobber(); bc::segmented_replace(c2.begin(), c2.end(), *pold_val, *pnew_val); escape(&c2); cptr pt(pold_val); pold_val = pnew_val; pnew_val = pt; } BOOST_FALLTHROUGH; case 6: { clobber(); bc::segmented_replace(c2.begin(), c2.end(), *pold_val, *pnew_val); escape(&c2); cptr pt(pold_val); pold_val = pnew_val; pnew_val = pt; } BOOST_FALLTHROUGH; case 5: { clobber(); bc::segmented_replace(c2.begin(), c2.end(), *pold_val, *pnew_val); escape(&c2); cptr pt(pold_val); pold_val = pnew_val; pnew_val = pt; } BOOST_FALLTHROUGH; case 4: { clobber(); bc::segmented_replace(c2.begin(), c2.end(), *pold_val, *pnew_val); escape(&c2); cptr pt(pold_val); pold_val = pnew_val; pnew_val = pt; } BOOST_FALLTHROUGH; case 3: { clobber(); bc::segmented_replace(c2.begin(), c2.end(), *pold_val, *pnew_val); escape(&c2); cptr pt(pold_val); pold_val = pnew_val; pnew_val = pt; } BOOST_FALLTHROUGH; case 2: { clobber(); bc::segmented_replace(c2.begin(), c2.end(), *pold_val, *pnew_val); escape(&c2); cptr pt(pold_val); pold_val = pnew_val; pnew_val = pt; } BOOST_FALLTHROUGH; case 1: { clobber(); bc::segmented_replace(c2.begin(), c2.end(), *pold_val, *pnew_val); escape(&c2); cptr pt(pold_val); pold_val = pnew_val; pnew_val = pt; } if (BOOST_UNLIKELY(--n_ == 0)) { t2.stop(); break; } } while (true); } } double r1 = calc_ns_per_elem(t1.elapsed().wall, iters, c.size()); double r2 = calc_ns_per_elem(t2.elapsed().wall, iters, c.size()); print_ratio(label, cname, r1, r2); } template void bench_replace_if(const C &c, std::size_t iters, const char* cname, Pred pred, const typename C::value_type& new_val, const char* label) { cpu_timer t1; { C c1(c), c2(c), c3(c), c4(c), c5(c), c6(c), c7(c), c8(c); std::size_t n_ = (iters + 7) / 8; t1.resume(); switch (iters % 8) { case 0: do { t1.resume(); { clobber(); std::replace_if(c1.begin(), c1.end(), pred, new_val); escape(&c1); } BOOST_FALLTHROUGH; case 7: { clobber(); std::replace_if(c2.begin(), c2.end(), pred, new_val); escape(&c2); } BOOST_FALLTHROUGH; case 6: { clobber(); std::replace_if(c3.begin(), c3.end(), pred, new_val); escape(&c3); } BOOST_FALLTHROUGH; case 5: { clobber(); std::replace_if(c4.begin(), c4.end(), pred, new_val); escape(&c4); } BOOST_FALLTHROUGH; case 4: { clobber(); std::replace_if(c5.begin(), c5.end(), pred, new_val); escape(&c5); } BOOST_FALLTHROUGH; case 3: { clobber(); std::replace_if(c6.begin(), c6.end(), pred, new_val); escape(&c6); } BOOST_FALLTHROUGH; case 2: { clobber(); std::replace_if(c7.begin(), c7.end(), pred, new_val); escape(&c7); } BOOST_FALLTHROUGH; case 1: { clobber(); std::replace_if(c8.begin(), c8.end(), pred, new_val); escape(&c8); } t1.stop(); if (BOOST_UNLIKELY(--n_ == 0)) { break; } c1 = c2 = c3 = c4 = c5 = c6 = c7 = c8 = c; } while (true); } } cpu_timer t2; { C c1(c), c2(c), c3(c), c4(c), c5(c), c6(c), c7(c), c8(c); std::size_t n_ = (iters + 7) / 8; t2.resume(); switch (iters % 8) { case 0: do { t2.resume(); { clobber(); bc::segmented_replace_if(c1.begin(), c1.end(), pred, new_val); escape(&c1); } BOOST_FALLTHROUGH; case 7: { clobber(); bc::segmented_replace_if(c2.begin(), c2.end(), pred, new_val); escape(&c2); } BOOST_FALLTHROUGH; case 6: { clobber(); bc::segmented_replace_if(c3.begin(), c3.end(), pred, new_val); escape(&c3); } BOOST_FALLTHROUGH; case 5: { clobber(); bc::segmented_replace_if(c4.begin(), c4.end(), pred, new_val); escape(&c4); } BOOST_FALLTHROUGH; case 4: { clobber(); bc::segmented_replace_if(c5.begin(), c5.end(), pred, new_val); escape(&c5); } BOOST_FALLTHROUGH; case 3: { clobber(); bc::segmented_replace_if(c6.begin(), c6.end(), pred, new_val); escape(&c6); } BOOST_FALLTHROUGH; case 2: { clobber(); bc::segmented_replace_if(c7.begin(), c7.end(), pred, new_val); escape(&c7); } BOOST_FALLTHROUGH; case 1: { clobber(); bc::segmented_replace_if(c8.begin(), c8.end(), pred, new_val); escape(&c8); } t2.stop(); if (BOOST_UNLIKELY(--n_ == 0)) { break; } c1 = c2 = c3 = c4 = c5 = c6 = c7 = c8 = c; } while (true); } } double r1 = calc_ns_per_elem(t1.elapsed().wall, iters, c.size()); double r2 = calc_ns_per_elem(t2.elapsed().wall, iters, c.size()); print_ratio(label, cname, r1, r2); } template void bench_transform(const C &c, std::size_t iters, const char* cname) { typedef typename C::value_type VT; boost::container::vector out(c.size()); cpu_timer t1; { std::size_t n_ = (iters + 7) / 8; t1.resume(); switch (iters % 8) { case 0: do { { clobber(); std::transform(c.begin(), c.end(), out.begin(), add_one()); escape(&out[0]); } BOOST_FALLTHROUGH; case 7: { clobber(); std::transform(c.begin(), c.end(), out.begin(), add_one()); escape(&out[0]); } BOOST_FALLTHROUGH; case 6: { clobber(); std::transform(c.begin(), c.end(), out.begin(), add_one()); escape(&out[0]); } BOOST_FALLTHROUGH; case 5: { clobber(); std::transform(c.begin(), c.end(), out.begin(), add_one()); escape(&out[0]); } BOOST_FALLTHROUGH; case 4: { clobber(); std::transform(c.begin(), c.end(), out.begin(), add_one()); escape(&out[0]); } BOOST_FALLTHROUGH; case 3: { clobber(); std::transform(c.begin(), c.end(), out.begin(), add_one()); escape(&out[0]); } BOOST_FALLTHROUGH; case 2: { clobber(); std::transform(c.begin(), c.end(), out.begin(), add_one()); escape(&out[0]); } BOOST_FALLTHROUGH; case 1: { clobber(); std::transform(c.begin(), c.end(), out.begin(), add_one()); escape(&out[0]); } if (BOOST_UNLIKELY(--n_ == 0)) { t1.stop(); break; } } while (true); } } cpu_timer t2; { std::size_t n_ = (iters + 7) / 8; t2.resume(); switch (iters % 8) { case 0: do { { clobber(); bc::segmented_transform(c.begin(), c.end(), out.begin(), add_one()); escape(&out[0]); } BOOST_FALLTHROUGH; case 7: { clobber(); bc::segmented_transform(c.begin(), c.end(), out.begin(), add_one()); escape(&out[0]); } BOOST_FALLTHROUGH; case 6: { clobber(); bc::segmented_transform(c.begin(), c.end(), out.begin(), add_one()); escape(&out[0]); } BOOST_FALLTHROUGH; case 5: { clobber(); bc::segmented_transform(c.begin(), c.end(), out.begin(), add_one()); escape(&out[0]); } BOOST_FALLTHROUGH; case 4: { clobber(); bc::segmented_transform(c.begin(), c.end(), out.begin(), add_one()); escape(&out[0]); } BOOST_FALLTHROUGH; case 3: { clobber(); bc::segmented_transform(c.begin(), c.end(), out.begin(), add_one()); escape(&out[0]); } BOOST_FALLTHROUGH; case 2: { clobber(); bc::segmented_transform(c.begin(), c.end(), out.begin(), add_one()); escape(&out[0]); } BOOST_FALLTHROUGH; case 1: { clobber(); bc::segmented_transform(c.begin(), c.end(), out.begin(), add_one()); escape(&out[0]); } if (BOOST_UNLIKELY(--n_ == 0)) { t2.stop(); break; } } while (true); } } double r1 = calc_ns_per_elem(t1.elapsed().wall, iters, c.size()); double r2 = calc_ns_per_elem(t2.elapsed().wall, iters, c.size()); print_ratio("transform", cname, r1, r2); } template void bench_fill_n(const C &c, std::size_t iters, const char* cname) { typedef typename C::value_type VT; VT val(42); typename C::difference_type n = static_cast(c.size()); C c2(c); cpu_timer t1; { std::size_t n_ = (iters + 7) / 8; t1.resume(); switch (iters % 8) { case 0: do { { clobber(); std::fill_n(c2.begin(), n, val); escape(&c2); } BOOST_FALLTHROUGH; case 7: { clobber(); std::fill_n(c2.begin(), n, val); escape(&c2); } BOOST_FALLTHROUGH; case 6: { clobber(); std::fill_n(c2.begin(), n, val); escape(&c2); } BOOST_FALLTHROUGH; case 5: { clobber(); std::fill_n(c2.begin(), n, val); escape(&c2); } BOOST_FALLTHROUGH; case 4: { clobber(); std::fill_n(c2.begin(), n, val); escape(&c2); } BOOST_FALLTHROUGH; case 3: { clobber(); std::fill_n(c2.begin(), n, val); escape(&c2); } BOOST_FALLTHROUGH; case 2: { clobber(); std::fill_n(c2.begin(), n, val); escape(&c2); } BOOST_FALLTHROUGH; case 1: { clobber(); std::fill_n(c2.begin(), n, val); escape(&c2); } if (BOOST_UNLIKELY(--n_ == 0)) { t1.stop(); break; } } while (true); } } cpu_timer t2; { std::size_t n_ = (iters + 7) / 8; t2.resume(); switch (iters % 8) { case 0: do { { clobber(); bc::segmented_fill_n(c2.begin(), n, val); escape(&c2); } BOOST_FALLTHROUGH; case 7: { clobber(); bc::segmented_fill_n(c2.begin(), n, val); escape(&c2); } BOOST_FALLTHROUGH; case 6: { clobber(); bc::segmented_fill_n(c2.begin(), n, val); escape(&c2); } BOOST_FALLTHROUGH; case 5: { clobber(); bc::segmented_fill_n(c2.begin(), n, val); escape(&c2); } BOOST_FALLTHROUGH; case 4: { clobber(); bc::segmented_fill_n(c2.begin(), n, val); escape(&c2); } BOOST_FALLTHROUGH; case 3: { clobber(); bc::segmented_fill_n(c2.begin(), n, val); escape(&c2); } BOOST_FALLTHROUGH; case 2: { clobber(); bc::segmented_fill_n(c2.begin(), n, val); escape(&c2); } BOOST_FALLTHROUGH; case 1: { clobber(); bc::segmented_fill_n(c2.begin(), n, val); escape(&c2); } if (BOOST_UNLIKELY(--n_ == 0)) { t2.stop(); break; } } while (true); } } double r1 = calc_ns_per_elem(t1.elapsed().wall, iters, c.size()); double r2 = calc_ns_per_elem(t2.elapsed().wall, iters, c.size()); print_ratio("fill_n", cname, r1, r2); } template void bench_copy_n(const C &c, std::size_t iters, const char* cname) { typedef typename C::value_type VT; boost::container::vector out(c.size()); typename C::difference_type n = static_cast(c.size()); cpu_timer t1; { std::size_t n_ = (iters + 7) / 8; t1.resume(); switch (iters % 8) { case 0: do { { clobber(); bench_detail::copy_n(c.begin(), n, out.begin()); escape(&out[0]); } BOOST_FALLTHROUGH; case 7: { clobber(); bench_detail::copy_n(c.begin(), n, out.begin()); escape(&out[0]); } BOOST_FALLTHROUGH; case 6: { clobber(); bench_detail::copy_n(c.begin(), n, out.begin()); escape(&out[0]); } BOOST_FALLTHROUGH; case 5: { clobber(); bench_detail::copy_n(c.begin(), n, out.begin()); escape(&out[0]); } BOOST_FALLTHROUGH; case 4: { clobber(); bench_detail::copy_n(c.begin(), n, out.begin()); escape(&out[0]); } BOOST_FALLTHROUGH; case 3: { clobber(); bench_detail::copy_n(c.begin(), n, out.begin()); escape(&out[0]); } BOOST_FALLTHROUGH; case 2: { clobber(); bench_detail::copy_n(c.begin(), n, out.begin()); escape(&out[0]); } BOOST_FALLTHROUGH; case 1: { clobber(); bench_detail::copy_n(c.begin(), n, out.begin()); escape(&out[0]); } if (BOOST_UNLIKELY(--n_ == 0)) { t1.stop(); break; } } while (true); } } cpu_timer t2; { std::size_t n_ = (iters + 7) / 8; t2.resume(); switch (iters % 8) { case 0: do { { clobber(); bc::segmented_copy_n(c.begin(), n, out.begin()); escape(&out[0]); } BOOST_FALLTHROUGH; case 7: { clobber(); bc::segmented_copy_n(c.begin(), n, out.begin()); escape(&out[0]); } BOOST_FALLTHROUGH; case 6: { clobber(); bc::segmented_copy_n(c.begin(), n, out.begin()); escape(&out[0]); } BOOST_FALLTHROUGH; case 5: { clobber(); bc::segmented_copy_n(c.begin(), n, out.begin()); escape(&out[0]); } BOOST_FALLTHROUGH; case 4: { clobber(); bc::segmented_copy_n(c.begin(), n, out.begin()); escape(&out[0]); } BOOST_FALLTHROUGH; case 3: { clobber(); bc::segmented_copy_n(c.begin(), n, out.begin()); escape(&out[0]); } BOOST_FALLTHROUGH; case 2: { clobber(); bc::segmented_copy_n(c.begin(), n, out.begin()); escape(&out[0]); } BOOST_FALLTHROUGH; case 1: { clobber(); bc::segmented_copy_n(c.begin(), n, out.begin()); escape(&out[0]); } if (BOOST_UNLIKELY(--n_ == 0)) { t2.stop(); break; } } while (true); } } double r1 = calc_ns_per_elem(t1.elapsed().wall, iters, c.size()); double r2 = calc_ns_per_elem(t2.elapsed().wall, iters, c.size()); print_ratio("copy_n", cname, r1, r2); } template void bench_generate(const C &c, std::size_t iters, const char* cname) { typedef typename C::value_type VT; C c2(c); int result = 0; cpu_timer t1; { std::size_t n_ = (iters + 7) / 8; t1.resume(); switch (iters % 8) { case 0: do { { clobber(); std::generate(c2.begin(), c2.end(), counter()); result = int_value(*c2.begin()); escape(&result); } BOOST_FALLTHROUGH; case 7: { clobber(); std::generate(c2.begin(), c2.end(), counter()); result = int_value(*c2.begin()); escape(&result); } BOOST_FALLTHROUGH; case 6: { clobber(); std::generate(c2.begin(), c2.end(), counter()); result = int_value(*c2.begin()); escape(&result); } BOOST_FALLTHROUGH; case 5: { clobber(); std::generate(c2.begin(), c2.end(), counter()); result = int_value(*c2.begin()); escape(&result); } BOOST_FALLTHROUGH; case 4: { clobber(); std::generate(c2.begin(), c2.end(), counter()); result = int_value(*c2.begin()); escape(&result); } BOOST_FALLTHROUGH; case 3: { clobber(); std::generate(c2.begin(), c2.end(), counter()); result = int_value(*c2.begin()); escape(&result); } BOOST_FALLTHROUGH; case 2: { clobber(); std::generate(c2.begin(), c2.end(), counter()); result = int_value(*c2.begin()); escape(&result); } BOOST_FALLTHROUGH; case 1: { clobber(); std::generate(c2.begin(), c2.end(), counter()); result = int_value(*c2.begin()); escape(&result); } if (BOOST_UNLIKELY(--n_ == 0)) { t1.stop(); break; } } while (true); } } cpu_timer t2; { std::size_t n_ = (iters + 7) / 8; t2.resume(); switch (iters % 8) { case 0: do { { clobber(); bc::segmented_generate(c2.begin(), c2.end(), counter()); result = int_value(*c2.begin()); escape(&result); } BOOST_FALLTHROUGH; case 7: { clobber(); bc::segmented_generate(c2.begin(), c2.end(), counter()); result = int_value(*c2.begin()); escape(&result); } BOOST_FALLTHROUGH; case 6: { clobber(); bc::segmented_generate(c2.begin(), c2.end(), counter()); result = int_value(*c2.begin()); escape(&result); } BOOST_FALLTHROUGH; case 5: { clobber(); bc::segmented_generate(c2.begin(), c2.end(), counter()); result = int_value(*c2.begin()); escape(&result); } BOOST_FALLTHROUGH; case 4: { clobber(); bc::segmented_generate(c2.begin(), c2.end(), counter()); result = int_value(*c2.begin()); escape(&result); } BOOST_FALLTHROUGH; case 3: { clobber(); bc::segmented_generate(c2.begin(), c2.end(), counter()); result = int_value(*c2.begin()); escape(&result); } BOOST_FALLTHROUGH; case 2: { clobber(); bc::segmented_generate(c2.begin(), c2.end(), counter()); result = int_value(*c2.begin()); escape(&result); } BOOST_FALLTHROUGH; case 1: { clobber(); bc::segmented_generate(c2.begin(), c2.end(), counter()); result = int_value(*c2.begin()); escape(&result); } if (BOOST_UNLIKELY(--n_ == 0)) { t2.stop(); break; } } while (true); } } double r1 = calc_ns_per_elem(t1.elapsed().wall, iters, c.size()); double r2 = calc_ns_per_elem(t2.elapsed().wall, iters, c.size()); print_ratio("generate", cname, r1, r2); } template void bench_generate_n(const C &c, std::size_t iters, const char* cname) { typedef typename C::value_type VT; typename C::difference_type n = static_cast(c.size()); C c2(c); int result = 0; cpu_timer t1; { std::size_t n_ = (iters + 7) / 8; t1.resume(); switch (iters % 8) { case 0: do { { clobber(); std::generate_n(c2.begin(), n, counter()); result = int_value(*c2.begin()); escape(&result); } BOOST_FALLTHROUGH; case 7: { clobber(); std::generate_n(c2.begin(), n, counter()); result = int_value(*c2.begin()); escape(&result); } BOOST_FALLTHROUGH; case 6: { clobber(); std::generate_n(c2.begin(), n, counter()); result = int_value(*c2.begin()); escape(&result); } BOOST_FALLTHROUGH; case 5: { clobber(); std::generate_n(c2.begin(), n, counter()); result = int_value(*c2.begin()); escape(&result); } BOOST_FALLTHROUGH; case 4: { clobber(); std::generate_n(c2.begin(), n, counter()); result = int_value(*c2.begin()); escape(&result); } BOOST_FALLTHROUGH; case 3: { clobber(); std::generate_n(c2.begin(), n, counter()); result = int_value(*c2.begin()); escape(&result); } BOOST_FALLTHROUGH; case 2: { clobber(); std::generate_n(c2.begin(), n, counter()); result = int_value(*c2.begin()); escape(&result); } BOOST_FALLTHROUGH; case 1: { clobber(); std::generate_n(c2.begin(), n, counter()); result = int_value(*c2.begin()); escape(&result); } if (BOOST_UNLIKELY(--n_ == 0)) { t1.stop(); break; } } while (true); } } cpu_timer t2; { std::size_t n_ = (iters + 7) / 8; t2.resume(); switch (iters % 8) { case 0: do { { clobber(); bc::segmented_generate_n(c2.begin(), n, counter()); result = int_value(*c2.begin()); escape(&result); } BOOST_FALLTHROUGH; case 7: { clobber(); bc::segmented_generate_n(c2.begin(), n, counter()); result = int_value(*c2.begin()); escape(&result); } BOOST_FALLTHROUGH; case 6: { clobber(); bc::segmented_generate_n(c2.begin(), n, counter()); result = int_value(*c2.begin()); escape(&result); } BOOST_FALLTHROUGH; case 5: { clobber(); bc::segmented_generate_n(c2.begin(), n, counter()); result = int_value(*c2.begin()); escape(&result); } BOOST_FALLTHROUGH; case 4: { clobber(); bc::segmented_generate_n(c2.begin(), n, counter()); result = int_value(*c2.begin()); escape(&result); } BOOST_FALLTHROUGH; case 3: { clobber(); bc::segmented_generate_n(c2.begin(), n, counter()); result = int_value(*c2.begin()); escape(&result); } BOOST_FALLTHROUGH; case 2: { clobber(); bc::segmented_generate_n(c2.begin(), n, counter()); result = int_value(*c2.begin()); escape(&result); } BOOST_FALLTHROUGH; case 1: { clobber(); bc::segmented_generate_n(c2.begin(), n, counter()); result = int_value(*c2.begin()); escape(&result); } if (BOOST_UNLIKELY(--n_ == 0)) { t2.stop(); break; } } while (true); } } double r1 = calc_ns_per_elem(t1.elapsed().wall, iters, c.size()); double r2 = calc_ns_per_elem(t2.elapsed().wall, iters, c.size()); print_ratio("generate_n", cname, r1, r2); } template void bench_remove(const C &c, std::size_t iters, const char* cname, const typename C::value_type& val, const char* label) { typedef typename C::iterator it_t; int result = 0; cpu_timer t1; { C c1(c), c2(c), c3(c), c4(c), c5(c), c6(c), c7(c), c8(c); std::size_t n_ = (iters + 7) / 8; t1.resume(); switch (iters % 8) { case 0: do { t1.resume(); { clobber(); it_t it = std::remove(c1.begin(), c1.end(), val); result = (it == c1.end()) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 7: { clobber(); it_t it = std::remove(c2.begin(), c2.end(), val); result = (it == c2.end()) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 6: { clobber(); it_t it = std::remove(c3.begin(), c3.end(), val); result = (it == c3.end()) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 5: { clobber(); it_t it = std::remove(c4.begin(), c4.end(), val); result = (it == c4.end()) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 4: { clobber(); it_t it = std::remove(c5.begin(), c5.end(), val); result = (it == c5.end()) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 3: { clobber(); it_t it = std::remove(c6.begin(), c6.end(), val); result = (it == c6.end()) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 2: { clobber(); it_t it = std::remove(c7.begin(), c7.end(), val); result = (it == c7.end()) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 1: { clobber(); it_t it = std::remove(c8.begin(), c8.end(), val); result = (it == c8.end()) ? 1 : 0; escape(&result); } t1.stop(); if (BOOST_UNLIKELY(--n_ == 0)) { break; } c1 = c2 = c3 = c4 = c5 = c6 = c7 = c8 = c; } while (true); } } cpu_timer t2; { C c1(c), c2(c), c3(c), c4(c), c5(c), c6(c), c7(c), c8(c); std::size_t n_ = (iters + 7) / 8; t2.resume(); switch (iters % 8) { case 0: do { t2.resume(); { clobber(); it_t it = bc::segmented_remove(c1.begin(), c1.end(), val); result = (it == c1.end()) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 7: { clobber(); it_t it = bc::segmented_remove(c2.begin(), c2.end(), val); result = (it == c2.end()) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 6: { clobber(); it_t it = bc::segmented_remove(c3.begin(), c3.end(), val); result = (it == c3.end()) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 5: { clobber(); it_t it = bc::segmented_remove(c4.begin(), c4.end(), val); result = (it == c4.end()) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 4: { clobber(); it_t it = bc::segmented_remove(c5.begin(), c5.end(), val); result = (it == c5.end()) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 3: { clobber(); it_t it = bc::segmented_remove(c6.begin(), c6.end(), val); result = (it == c6.end()) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 2: { clobber(); it_t it = bc::segmented_remove(c7.begin(), c7.end(), val); result = (it == c7.end()) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 1: { clobber(); it_t it = bc::segmented_remove(c8.begin(), c8.end(), val); result = (it == c8.end()) ? 1 : 0; escape(&result); } t2.stop(); if (BOOST_UNLIKELY(--n_ == 0)) { break; } c1 = c2 = c3 = c4 = c5 = c6 = c7 = c8 = c; } while (true); } } double r1 = calc_ns_per_elem(t1.elapsed().wall, iters, c.size()); double r2 = calc_ns_per_elem(t2.elapsed().wall, iters, c.size()); print_ratio(label, cname, r1, r2); } template void bench_remove_if(const C &c, std::size_t iters, const char* cname, Pred pred, const char* label) { typedef typename C::iterator it_t; int result = 0; cpu_timer t1; { C c1(c), c2(c), c3(c), c4(c), c5(c), c6(c), c7(c), c8(c); std::size_t n_ = (iters + 7) / 8; t1.resume(); switch (iters % 8) { case 0: do { t1.resume(); { clobber(); it_t it = std::remove_if(c1.begin(), c1.end(), pred); result = (it == c1.end()) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 7: { clobber(); it_t it = std::remove_if(c2.begin(), c2.end(), pred); result = (it == c2.end()) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 6: { clobber(); it_t it = std::remove_if(c3.begin(), c3.end(), pred); result = (it == c3.end()) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 5: { clobber(); it_t it = std::remove_if(c4.begin(), c4.end(), pred); result = (it == c4.end()) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 4: { clobber(); it_t it = std::remove_if(c5.begin(), c5.end(), pred); result = (it == c5.end()) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 3: { clobber(); it_t it = std::remove_if(c6.begin(), c6.end(), pred); result = (it == c6.end()) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 2: { clobber(); it_t it = std::remove_if(c7.begin(), c7.end(), pred); result = (it == c7.end()) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 1: { clobber(); it_t it = std::remove_if(c8.begin(), c8.end(), pred); result = (it == c8.end()) ? 1 : 0; escape(&result); } t1.stop(); if (BOOST_UNLIKELY(--n_ == 0)) { break; } c1 = c2 = c3 = c4 = c5 = c6 = c7 = c8 = c; } while (true); } } cpu_timer t2; { C c1(c), c2(c), c3(c), c4(c), c5(c), c6(c), c7(c), c8(c); std::size_t n_ = (iters + 7) / 8; t2.resume(); switch (iters % 8) { case 0: do { t2.resume(); { clobber(); it_t it = bc::segmented_remove_if(c1.begin(), c1.end(), pred); result = (it == c1.end()) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 7: { clobber(); it_t it = bc::segmented_remove_if(c2.begin(), c2.end(), pred); result = (it == c2.end()) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 6: { clobber(); it_t it = bc::segmented_remove_if(c3.begin(), c3.end(), pred); result = (it == c3.end()) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 5: { clobber(); it_t it = bc::segmented_remove_if(c4.begin(), c4.end(), pred); result = (it == c4.end()) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 4: { clobber(); it_t it = bc::segmented_remove_if(c5.begin(), c5.end(), pred); result = (it == c5.end()) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 3: { clobber(); it_t it = bc::segmented_remove_if(c6.begin(), c6.end(), pred); result = (it == c6.end()) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 2: { clobber(); it_t it = bc::segmented_remove_if(c7.begin(), c7.end(), pred); result = (it == c7.end()) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 1: { clobber(); it_t it = bc::segmented_remove_if(c8.begin(), c8.end(), pred); result = (it == c8.end()) ? 1 : 0; escape(&result); } t2.stop(); if (BOOST_UNLIKELY(--n_ == 0)) { break; } c1 = c2 = c3 = c4 = c5 = c6 = c7 = c8 = c; } while (true); } } double r1 = calc_ns_per_elem(t1.elapsed().wall, iters, c.size()); double r2 = calc_ns_per_elem(t2.elapsed().wall, iters, c.size()); print_ratio(label, cname, r1, r2); } template void bench_remove_copy(const C &c, std::size_t iters, const char* cname, const typename C::value_type& val, const char* label) { typedef typename C::value_type VT; typedef typename boost::move_detail::if_c, boost::container::vector >::type out_t; out_t out(c.size()); cpu_timer t1; { std::size_t n_ = (iters + 7) / 8; t1.resume(); switch (iters % 8) { case 0: do { { clobber(); std::remove_copy(c.begin(), c.end(), out.begin(), val); escape(&out[0]); } BOOST_FALLTHROUGH; case 7: { clobber(); std::remove_copy(c.begin(), c.end(), out.begin(), val); escape(&out[0]); } BOOST_FALLTHROUGH; case 6: { clobber(); std::remove_copy(c.begin(), c.end(), out.begin(), val); escape(&out[0]); } BOOST_FALLTHROUGH; case 5: { clobber(); std::remove_copy(c.begin(), c.end(), out.begin(), val); escape(&out[0]); } BOOST_FALLTHROUGH; case 4: { clobber(); std::remove_copy(c.begin(), c.end(), out.begin(), val); escape(&out[0]); } BOOST_FALLTHROUGH; case 3: { clobber(); std::remove_copy(c.begin(), c.end(), out.begin(), val); escape(&out[0]); } BOOST_FALLTHROUGH; case 2: { clobber(); std::remove_copy(c.begin(), c.end(), out.begin(), val); escape(&out[0]); } BOOST_FALLTHROUGH; case 1: { clobber(); std::remove_copy(c.begin(), c.end(), out.begin(), val); escape(&out[0]); } if (BOOST_UNLIKELY(--n_ == 0)) { t1.stop(); break; } } while (true); } } cpu_timer t2; { std::size_t n_ = (iters + 7) / 8; t2.resume(); switch (iters % 8) { case 0: do { { clobber(); bc::segmented_remove_copy(c.begin(), c.end(), out.begin(), val); escape(&out[0]); } BOOST_FALLTHROUGH; case 7: { clobber(); bc::segmented_remove_copy(c.begin(), c.end(), out.begin(), val); escape(&out[0]); } BOOST_FALLTHROUGH; case 6: { clobber(); bc::segmented_remove_copy(c.begin(), c.end(), out.begin(), val); escape(&out[0]); } BOOST_FALLTHROUGH; case 5: { clobber(); bc::segmented_remove_copy(c.begin(), c.end(), out.begin(), val); escape(&out[0]); } BOOST_FALLTHROUGH; case 4: { clobber(); bc::segmented_remove_copy(c.begin(), c.end(), out.begin(), val); escape(&out[0]); } BOOST_FALLTHROUGH; case 3: { clobber(); bc::segmented_remove_copy(c.begin(), c.end(), out.begin(), val); escape(&out[0]); } BOOST_FALLTHROUGH; case 2: { clobber(); bc::segmented_remove_copy(c.begin(), c.end(), out.begin(), val); escape(&out[0]); } BOOST_FALLTHROUGH; case 1: { clobber(); bc::segmented_remove_copy(c.begin(), c.end(), out.begin(), val); escape(&out[0]); } if (BOOST_UNLIKELY(--n_ == 0)) { t2.stop(); break; } } while (true); } } double r1 = calc_ns_per_elem(t1.elapsed().wall, iters, c.size()); double r2 = calc_ns_per_elem(t2.elapsed().wall, iters, c.size()); print_ratio(label, cname, r1, r2); } template void bench_remove_copy_if(const C &c, std::size_t iters, const char* cname, Pred pred, const char* label) { typedef typename C::value_type VT; typedef typename boost::move_detail::if_c, boost::container::vector >::type out_t; out_t out(c.size()); cpu_timer t1; { std::size_t n_ = (iters + 7) / 8; t1.resume(); switch (iters % 8) { case 0: do { { clobber(); std::remove_copy_if(c.begin(), c.end(), out.begin(), pred); escape(&out[0]); } BOOST_FALLTHROUGH; case 7: { clobber(); std::remove_copy_if(c.begin(), c.end(), out.begin(), pred); escape(&out[0]); } BOOST_FALLTHROUGH; case 6: { clobber(); std::remove_copy_if(c.begin(), c.end(), out.begin(), pred); escape(&out[0]); } BOOST_FALLTHROUGH; case 5: { clobber(); std::remove_copy_if(c.begin(), c.end(), out.begin(), pred); escape(&out[0]); } BOOST_FALLTHROUGH; case 4: { clobber(); std::remove_copy_if(c.begin(), c.end(), out.begin(), pred); escape(&out[0]); } BOOST_FALLTHROUGH; case 3: { clobber(); std::remove_copy_if(c.begin(), c.end(), out.begin(), pred); escape(&out[0]); } BOOST_FALLTHROUGH; case 2: { clobber(); std::remove_copy_if(c.begin(), c.end(), out.begin(), pred); escape(&out[0]); } BOOST_FALLTHROUGH; case 1: { clobber(); std::remove_copy_if(c.begin(), c.end(), out.begin(), pred); escape(&out[0]); } if (BOOST_UNLIKELY(--n_ == 0)) { t1.stop(); break; } } while (true); } } cpu_timer t2; { std::size_t n_ = (iters + 7) / 8; t2.resume(); switch (iters % 8) { case 0: do { { clobber(); bc::segmented_remove_copy_if(c.begin(), c.end(), out.begin(), pred); escape(&out[0]); } BOOST_FALLTHROUGH; case 7: { clobber(); bc::segmented_remove_copy_if(c.begin(), c.end(), out.begin(), pred); escape(&out[0]); } BOOST_FALLTHROUGH; case 6: { clobber(); bc::segmented_remove_copy_if(c.begin(), c.end(), out.begin(), pred); escape(&out[0]); } BOOST_FALLTHROUGH; case 5: { clobber(); bc::segmented_remove_copy_if(c.begin(), c.end(), out.begin(), pred); escape(&out[0]); } BOOST_FALLTHROUGH; case 4: { clobber(); bc::segmented_remove_copy_if(c.begin(), c.end(), out.begin(), pred); escape(&out[0]); } BOOST_FALLTHROUGH; case 3: { clobber(); bc::segmented_remove_copy_if(c.begin(), c.end(), out.begin(), pred); escape(&out[0]); } BOOST_FALLTHROUGH; case 2: { clobber(); bc::segmented_remove_copy_if(c.begin(), c.end(), out.begin(), pred); escape(&out[0]); } BOOST_FALLTHROUGH; case 1: { clobber(); bc::segmented_remove_copy_if(c.begin(), c.end(), out.begin(), pred); escape(&out[0]); } if (BOOST_UNLIKELY(--n_ == 0)) { t2.stop(); break; } } while (true); } } double r1 = calc_ns_per_elem(t1.elapsed().wall, iters, c.size()); double r2 = calc_ns_per_elem(t2.elapsed().wall, iters, c.size()); print_ratio(label, cname, r1, r2); } template void bench_reverse(const C &c, std::size_t iters, const char* cname) { C c2(c); int result = 0; cpu_timer t1; { std::size_t n_ = (iters + 7) / 8; t1.resume(); switch (iters % 8) { case 0: do { { clobber(); std::reverse(c2.begin(), c2.end()); result = int_value(*c2.begin()); escape(&result); } BOOST_FALLTHROUGH; case 7: { clobber(); std::reverse(c2.begin(), c2.end()); result = int_value(*c2.begin()); escape(&result); } BOOST_FALLTHROUGH; case 6: { clobber(); std::reverse(c2.begin(), c2.end()); result = int_value(*c2.begin()); escape(&result); } BOOST_FALLTHROUGH; case 5: { clobber(); std::reverse(c2.begin(), c2.end()); result = int_value(*c2.begin()); escape(&result); } BOOST_FALLTHROUGH; case 4: { clobber(); std::reverse(c2.begin(), c2.end()); result = int_value(*c2.begin()); escape(&result); } BOOST_FALLTHROUGH; case 3: { clobber(); std::reverse(c2.begin(), c2.end()); result = int_value(*c2.begin()); escape(&result); } BOOST_FALLTHROUGH; case 2: { clobber(); std::reverse(c2.begin(), c2.end()); result = int_value(*c2.begin()); escape(&result); } BOOST_FALLTHROUGH; case 1: { clobber(); std::reverse(c2.begin(), c2.end()); result = int_value(*c2.begin()); escape(&result); } if (BOOST_UNLIKELY(--n_ == 0)) { t1.stop(); break; } } while (true); } } cpu_timer t2; { std::size_t n_ = (iters + 7) / 8; t2.resume(); switch (iters % 8) { case 0: do { { clobber(); bc::segmented_reverse(c2.begin(), c2.end()); result = int_value(*c2.begin()); escape(&result); } BOOST_FALLTHROUGH; case 7: { clobber(); bc::segmented_reverse(c2.begin(), c2.end()); result = int_value(*c2.begin()); escape(&result); } BOOST_FALLTHROUGH; case 6: { clobber(); bc::segmented_reverse(c2.begin(), c2.end()); result = int_value(*c2.begin()); escape(&result); } BOOST_FALLTHROUGH; case 5: { clobber(); bc::segmented_reverse(c2.begin(), c2.end()); result = int_value(*c2.begin()); escape(&result); } BOOST_FALLTHROUGH; case 4: { clobber(); bc::segmented_reverse(c2.begin(), c2.end()); result = int_value(*c2.begin()); escape(&result); } BOOST_FALLTHROUGH; case 3: { clobber(); bc::segmented_reverse(c2.begin(), c2.end()); result = int_value(*c2.begin()); escape(&result); } BOOST_FALLTHROUGH; case 2: { clobber(); bc::segmented_reverse(c2.begin(), c2.end()); result = int_value(*c2.begin()); escape(&result); } BOOST_FALLTHROUGH; case 1: { clobber(); bc::segmented_reverse(c2.begin(), c2.end()); result = int_value(*c2.begin()); escape(&result); } if (BOOST_UNLIKELY(--n_ == 0)) { t2.stop(); break; } } while (true); } } double r1 = calc_ns_per_elem(t1.elapsed().wall, iters, c.size()); double r2 = calc_ns_per_elem(t2.elapsed().wall, iters, c.size()); print_ratio("reverse", cname, r1, r2); } template void bench_reverse_copy(const C &c, std::size_t iters, const char* cname) { typedef typename C::value_type VT; boost::container::vector out(c.size()); cpu_timer t1; { std::size_t n_ = (iters + 7) / 8; t1.resume(); switch (iters % 8) { case 0: do { { clobber(); std::reverse_copy(c.begin(), c.end(), out.begin()); escape(&out[0]); } BOOST_FALLTHROUGH; case 7: { clobber(); std::reverse_copy(c.begin(), c.end(), out.begin()); escape(&out[0]); } BOOST_FALLTHROUGH; case 6: { clobber(); std::reverse_copy(c.begin(), c.end(), out.begin()); escape(&out[0]); } BOOST_FALLTHROUGH; case 5: { clobber(); std::reverse_copy(c.begin(), c.end(), out.begin()); escape(&out[0]); } BOOST_FALLTHROUGH; case 4: { clobber(); std::reverse_copy(c.begin(), c.end(), out.begin()); escape(&out[0]); } BOOST_FALLTHROUGH; case 3: { clobber(); std::reverse_copy(c.begin(), c.end(), out.begin()); escape(&out[0]); } BOOST_FALLTHROUGH; case 2: { clobber(); std::reverse_copy(c.begin(), c.end(), out.begin()); escape(&out[0]); } BOOST_FALLTHROUGH; case 1: { clobber(); std::reverse_copy(c.begin(), c.end(), out.begin()); escape(&out[0]); } if (BOOST_UNLIKELY(--n_ == 0)) { t1.stop(); break; } } while (true); } } cpu_timer t2; { std::size_t n_ = (iters + 7) / 8; t2.resume(); switch (iters % 8) { case 0: do { { clobber(); bc::segmented_reverse_copy(c.begin(), c.end(), out.begin()); escape(&out[0]); } BOOST_FALLTHROUGH; case 7: { clobber(); bc::segmented_reverse_copy(c.begin(), c.end(), out.begin()); escape(&out[0]); } BOOST_FALLTHROUGH; case 6: { clobber(); bc::segmented_reverse_copy(c.begin(), c.end(), out.begin()); escape(&out[0]); } BOOST_FALLTHROUGH; case 5: { clobber(); bc::segmented_reverse_copy(c.begin(), c.end(), out.begin()); escape(&out[0]); } BOOST_FALLTHROUGH; case 4: { clobber(); bc::segmented_reverse_copy(c.begin(), c.end(), out.begin()); escape(&out[0]); } BOOST_FALLTHROUGH; case 3: { clobber(); bc::segmented_reverse_copy(c.begin(), c.end(), out.begin()); escape(&out[0]); } BOOST_FALLTHROUGH; case 2: { clobber(); bc::segmented_reverse_copy(c.begin(), c.end(), out.begin()); escape(&out[0]); } BOOST_FALLTHROUGH; case 1: { clobber(); bc::segmented_reverse_copy(c.begin(), c.end(), out.begin()); escape(&out[0]); } if (BOOST_UNLIKELY(--n_ == 0)) { t2.stop(); break; } } while (true); } } double r1 = calc_ns_per_elem(t1.elapsed().wall, iters, c.size()); double r2 = calc_ns_per_elem(t2.elapsed().wall, iters, c.size()); print_ratio("reverse_copy", cname, r1, r2); } template void bench_is_sorted(const C &c, std::size_t iters, const char* cname, const char* label) { int result = 0; cpu_timer t1; { std::size_t n_ = (iters + 7) / 8; t1.resume(); switch (iters % 8) { case 0: do { { clobber(); result = bench_detail::is_sorted(c.begin(), c.end()) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 7: { clobber(); result = bench_detail::is_sorted(c.begin(), c.end()) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 6: { clobber(); result = bench_detail::is_sorted(c.begin(), c.end()) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 5: { clobber(); result = bench_detail::is_sorted(c.begin(), c.end()) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 4: { clobber(); result = bench_detail::is_sorted(c.begin(), c.end()) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 3: { clobber(); result = bench_detail::is_sorted(c.begin(), c.end()) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 2: { clobber(); result = bench_detail::is_sorted(c.begin(), c.end()) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 1: { clobber(); result = bench_detail::is_sorted(c.begin(), c.end()) ? 1 : 0; escape(&result); } if (BOOST_UNLIKELY(--n_ == 0)) { t1.stop(); break; } } while (true); } } cpu_timer t2; { std::size_t n_ = (iters + 7) / 8; t2.resume(); switch (iters % 8) { case 0: do { { clobber(); result = bc::segmented_is_sorted(c.begin(), c.end()) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 7: { clobber(); result = bc::segmented_is_sorted(c.begin(), c.end()) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 6: { clobber(); result = bc::segmented_is_sorted(c.begin(), c.end()) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 5: { clobber(); result = bc::segmented_is_sorted(c.begin(), c.end()) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 4: { clobber(); result = bc::segmented_is_sorted(c.begin(), c.end()) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 3: { clobber(); result = bc::segmented_is_sorted(c.begin(), c.end()) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 2: { clobber(); result = bc::segmented_is_sorted(c.begin(), c.end()) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 1: { clobber(); result = bc::segmented_is_sorted(c.begin(), c.end()) ? 1 : 0; escape(&result); } if (BOOST_UNLIKELY(--n_ == 0)) { t2.stop(); break; } } while (true); } } double r1 = calc_ns_per_elem(t1.elapsed().wall, iters, c.size()); double r2 = calc_ns_per_elem(t2.elapsed().wall, iters, c.size()); print_ratio(label, cname, r1, r2); } template void bench_is_sorted_until(const C &c, std::size_t iters, const char* cname, const char* label) { typedef typename C::const_iterator cit_t; int result = 0; cpu_timer t1; { std::size_t n_ = (iters + 7) / 8; t1.resume(); switch (iters % 8) { case 0: do { { clobber(); cit_t it = bench_detail::is_sorted_until(c.begin(), c.end()); result = (it == c.end()) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 7: { clobber(); cit_t it = bench_detail::is_sorted_until(c.begin(), c.end()); result = (it == c.end()) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 6: { clobber(); cit_t it = bench_detail::is_sorted_until(c.begin(), c.end()); result = (it == c.end()) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 5: { clobber(); cit_t it = bench_detail::is_sorted_until(c.begin(), c.end()); result = (it == c.end()) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 4: { clobber(); cit_t it = bench_detail::is_sorted_until(c.begin(), c.end()); result = (it == c.end()) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 3: { clobber(); cit_t it = bench_detail::is_sorted_until(c.begin(), c.end()); result = (it == c.end()) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 2: { clobber(); cit_t it = bench_detail::is_sorted_until(c.begin(), c.end()); result = (it == c.end()) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 1: { clobber(); cit_t it = bench_detail::is_sorted_until(c.begin(), c.end()); result = (it == c.end()) ? 1 : 0; escape(&result); } if (BOOST_UNLIKELY(--n_ == 0)) { t1.stop(); break; } } while (true); } } cpu_timer t2; { std::size_t n_ = (iters + 7) / 8; t2.resume(); switch (iters % 8) { case 0: do { { clobber(); cit_t it = bc::segmented_is_sorted_until(c.begin(), c.end()); result = (it == c.end()) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 7: { clobber(); cit_t it = bc::segmented_is_sorted_until(c.begin(), c.end()); result = (it == c.end()) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 6: { clobber(); cit_t it = bc::segmented_is_sorted_until(c.begin(), c.end()); result = (it == c.end()) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 5: { clobber(); cit_t it = bc::segmented_is_sorted_until(c.begin(), c.end()); result = (it == c.end()) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 4: { clobber(); cit_t it = bc::segmented_is_sorted_until(c.begin(), c.end()); result = (it == c.end()) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 3: { clobber(); cit_t it = bc::segmented_is_sorted_until(c.begin(), c.end()); result = (it == c.end()) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 2: { clobber(); cit_t it = bc::segmented_is_sorted_until(c.begin(), c.end()); result = (it == c.end()) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 1: { clobber(); cit_t it = bc::segmented_is_sorted_until(c.begin(), c.end()); result = (it == c.end()) ? 1 : 0; escape(&result); } if (BOOST_UNLIKELY(--n_ == 0)) { t2.stop(); break; } } while (true); } } double r1 = calc_ns_per_elem(t1.elapsed().wall, iters, c.size()); double r2 = calc_ns_per_elem(t2.elapsed().wall, iters, c.size()); print_ratio(label, cname, r1, r2); } template void bench_is_partitioned(const C &c, std::size_t iters, const char* cname, Pred pred, const char* label) { int result = 0; cpu_timer t1; { std::size_t n_ = (iters + 7) / 8; t1.resume(); switch (iters % 8) { case 0: do { { clobber(); result = bench_detail::is_partitioned(c.begin(), c.end(), pred) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 7: { clobber(); result = bench_detail::is_partitioned(c.begin(), c.end(), pred) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 6: { clobber(); result = bench_detail::is_partitioned(c.begin(), c.end(), pred) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 5: { clobber(); result = bench_detail::is_partitioned(c.begin(), c.end(), pred) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 4: { clobber(); result = bench_detail::is_partitioned(c.begin(), c.end(), pred) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 3: { clobber(); result = bench_detail::is_partitioned(c.begin(), c.end(), pred) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 2: { clobber(); result = bench_detail::is_partitioned(c.begin(), c.end(), pred) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 1: { clobber(); result = bench_detail::is_partitioned(c.begin(), c.end(), pred) ? 1 : 0; escape(&result); } if (BOOST_UNLIKELY(--n_ == 0)) { t1.stop(); break; } } while (true); } } cpu_timer t2; { std::size_t n_ = (iters + 7) / 8; t2.resume(); switch (iters % 8) { case 0: do { { clobber(); result = bc::segmented_is_partitioned(c.begin(), c.end(), pred) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 7: { clobber(); result = bc::segmented_is_partitioned(c.begin(), c.end(), pred) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 6: { clobber(); result = bc::segmented_is_partitioned(c.begin(), c.end(), pred) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 5: { clobber(); result = bc::segmented_is_partitioned(c.begin(), c.end(), pred) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 4: { clobber(); result = bc::segmented_is_partitioned(c.begin(), c.end(), pred) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 3: { clobber(); result = bc::segmented_is_partitioned(c.begin(), c.end(), pred) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 2: { clobber(); result = bc::segmented_is_partitioned(c.begin(), c.end(), pred) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 1: { clobber(); result = bc::segmented_is_partitioned(c.begin(), c.end(), pred) ? 1 : 0; escape(&result); } if (BOOST_UNLIKELY(--n_ == 0)) { t2.stop(); break; } } while (true); } } double r1 = calc_ns_per_elem(t1.elapsed().wall, iters, c.size()); double r2 = calc_ns_per_elem(t2.elapsed().wall, iters, c.size()); print_ratio(label, cname, r1, r2); } template void bench_merge(const C &c, const C &c2, std::size_t iters, const char* cname) { typedef typename C::value_type VT; boost::container::vector out(c.size() + c2.size()); cpu_timer t1; { std::size_t n_ = (iters + 7) / 8; t1.resume(); switch (iters % 8) { case 0: do { { clobber(); std::merge(c.begin(), c.end(), c2.begin(), c2.end(), out.begin()); escape(&out[0]); } BOOST_FALLTHROUGH; case 7: { clobber(); std::merge(c.begin(), c.end(), c2.begin(), c2.end(), out.begin()); escape(&out[0]); } BOOST_FALLTHROUGH; case 6: { clobber(); std::merge(c.begin(), c.end(), c2.begin(), c2.end(), out.begin()); escape(&out[0]); } BOOST_FALLTHROUGH; case 5: { clobber(); std::merge(c.begin(), c.end(), c2.begin(), c2.end(), out.begin()); escape(&out[0]); } BOOST_FALLTHROUGH; case 4: { clobber(); std::merge(c.begin(), c.end(), c2.begin(), c2.end(), out.begin()); escape(&out[0]); } BOOST_FALLTHROUGH; case 3: { clobber(); std::merge(c.begin(), c.end(), c2.begin(), c2.end(), out.begin()); escape(&out[0]); } BOOST_FALLTHROUGH; case 2: { clobber(); std::merge(c.begin(), c.end(), c2.begin(), c2.end(), out.begin()); escape(&out[0]); } BOOST_FALLTHROUGH; case 1: { clobber(); std::merge(c.begin(), c.end(), c2.begin(), c2.end(), out.begin()); escape(&out[0]); } if (BOOST_UNLIKELY(--n_ == 0)) { t1.stop(); break; } } while (true); } } cpu_timer t2; { std::size_t n_ = (iters + 7) / 8; t2.resume(); switch (iters % 8) { case 0: do { { clobber(); bc::segmented_merge(c.begin(), c.end(), c2.begin(), c2.end(), out.begin()); escape(&out[0]); } BOOST_FALLTHROUGH; case 7: { clobber(); bc::segmented_merge(c.begin(), c.end(), c2.begin(), c2.end(), out.begin()); escape(&out[0]); } BOOST_FALLTHROUGH; case 6: { clobber(); bc::segmented_merge(c.begin(), c.end(), c2.begin(), c2.end(), out.begin()); escape(&out[0]); } BOOST_FALLTHROUGH; case 5: { clobber(); bc::segmented_merge(c.begin(), c.end(), c2.begin(), c2.end(), out.begin()); escape(&out[0]); } BOOST_FALLTHROUGH; case 4: { clobber(); bc::segmented_merge(c.begin(), c.end(), c2.begin(), c2.end(), out.begin()); escape(&out[0]); } BOOST_FALLTHROUGH; case 3: { clobber(); bc::segmented_merge(c.begin(), c.end(), c2.begin(), c2.end(), out.begin()); escape(&out[0]); } BOOST_FALLTHROUGH; case 2: { clobber(); bc::segmented_merge(c.begin(), c.end(), c2.begin(), c2.end(), out.begin()); escape(&out[0]); } BOOST_FALLTHROUGH; case 1: { clobber(); bc::segmented_merge(c.begin(), c.end(), c2.begin(), c2.end(), out.begin()); escape(&out[0]); } if (BOOST_UNLIKELY(--n_ == 0)) { t2.stop(); break; } } while (true); } } double r1 = calc_ns_per_elem(t1.elapsed().wall, iters, c.size()); double r2 = calc_ns_per_elem(t2.elapsed().wall, iters, c.size()); print_ratio("merge", cname, r1, r2); } template void bench_mismatch(const C &c, const C &c2, std::size_t iters, const char* cname, const char* label) { int result = 0; cpu_timer t1; { std::size_t n_ = (iters + 7) / 8; t1.resume(); switch (iters % 8) { case 0: do { { clobber(); result = (std::mismatch(c.begin(), c.end(), c2.begin()).first == c.end()) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 7: { clobber(); result = (std::mismatch(c.begin(), c.end(), c2.begin()).first == c.end()) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 6: { clobber(); result = (std::mismatch(c.begin(), c.end(), c2.begin()).first == c.end()) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 5: { clobber(); result = (std::mismatch(c.begin(), c.end(), c2.begin()).first == c.end()) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 4: { clobber(); result = (std::mismatch(c.begin(), c.end(), c2.begin()).first == c.end()) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 3: { clobber(); result = (std::mismatch(c.begin(), c.end(), c2.begin()).first == c.end()) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 2: { clobber(); result = (std::mismatch(c.begin(), c.end(), c2.begin()).first == c.end()) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 1: { clobber(); result = (std::mismatch(c.begin(), c.end(), c2.begin()).first == c.end()) ? 1 : 0; escape(&result); } if (BOOST_UNLIKELY(--n_ == 0)) { t1.stop(); break; } } while (true); } } cpu_timer t2; { std::size_t n_ = (iters + 7) / 8; t2.resume(); switch (iters % 8) { case 0: do { { clobber(); result = (bc::segmented_mismatch(c.begin(), c.end(), c2.begin()).first == c.end()) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 7: { clobber(); result = (bc::segmented_mismatch(c.begin(), c.end(), c2.begin()).first == c.end()) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 6: { clobber(); result = (bc::segmented_mismatch(c.begin(), c.end(), c2.begin()).first == c.end()) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 5: { clobber(); result = (bc::segmented_mismatch(c.begin(), c.end(), c2.begin()).first == c.end()) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 4: { clobber(); result = (bc::segmented_mismatch(c.begin(), c.end(), c2.begin()).first == c.end()) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 3: { clobber(); result = (bc::segmented_mismatch(c.begin(), c.end(), c2.begin()).first == c.end()) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 2: { clobber(); result = (bc::segmented_mismatch(c.begin(), c.end(), c2.begin()).first == c.end()) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 1: { clobber(); result = (bc::segmented_mismatch(c.begin(), c.end(), c2.begin()).first == c.end()) ? 1 : 0; escape(&result); } if (BOOST_UNLIKELY(--n_ == 0)) { t2.stop(); break; } } while (true); } } double r1 = calc_ns_per_elem(t1.elapsed().wall, iters, c.size()); double r2 = calc_ns_per_elem(t2.elapsed().wall, iters, c.size()); print_ratio(label, cname, r1, r2); } template void bench_swap_ranges(const C &c, std::size_t iters, const char* cname) { typedef typename C::iterator it_t; typedef typename C::value_type VT; C c2(c); C c3(c2); for (it_t it = c3.begin(), ite = c3.end(); it != ite; ++it) *it = VT(int_value(*it) * 3); int result = 0; cpu_timer t1; { std::size_t n_ = (iters + 7) / 8; t1.resume(); switch (iters % 8) { case 0: do { { clobber(); std::swap_ranges(c2.begin(), c2.end(), c3.begin()); result = int_value(*c2.begin()); escape(&result); } BOOST_FALLTHROUGH; case 7: { clobber(); std::swap_ranges(c2.begin(), c2.end(), c3.begin()); result = int_value(*c2.begin()); escape(&result); } BOOST_FALLTHROUGH; case 6: { clobber(); std::swap_ranges(c2.begin(), c2.end(), c3.begin()); result = int_value(*c2.begin()); escape(&result); } BOOST_FALLTHROUGH; case 5: { clobber(); std::swap_ranges(c2.begin(), c2.end(), c3.begin()); result = int_value(*c2.begin()); escape(&result); } BOOST_FALLTHROUGH; case 4: { clobber(); std::swap_ranges(c2.begin(), c2.end(), c3.begin()); result = int_value(*c2.begin()); escape(&result); } BOOST_FALLTHROUGH; case 3: { clobber(); std::swap_ranges(c2.begin(), c2.end(), c3.begin()); result = int_value(*c2.begin()); escape(&result); } BOOST_FALLTHROUGH; case 2: { clobber(); std::swap_ranges(c2.begin(), c2.end(), c3.begin()); result = int_value(*c2.begin()); escape(&result); } BOOST_FALLTHROUGH; case 1: { clobber(); std::swap_ranges(c2.begin(), c2.end(), c3.begin()); result = int_value(*c2.begin()); escape(&result); } if (BOOST_UNLIKELY(--n_ == 0)) { t1.stop(); break; } } while (true); } } cpu_timer t2; { std::size_t n_ = (iters + 7) / 8; t2.resume(); switch (iters % 8) { case 0: do { { clobber(); bc::segmented_swap_ranges(c2.begin(), c2.end(), c3.begin()); result = int_value(*c2.begin()); escape(&result); } BOOST_FALLTHROUGH; case 7: { clobber(); bc::segmented_swap_ranges(c2.begin(), c2.end(), c3.begin()); result = int_value(*c2.begin()); escape(&result); } BOOST_FALLTHROUGH; case 6: { clobber(); bc::segmented_swap_ranges(c2.begin(), c2.end(), c3.begin()); result = int_value(*c2.begin()); escape(&result); } BOOST_FALLTHROUGH; case 5: { clobber(); bc::segmented_swap_ranges(c2.begin(), c2.end(), c3.begin()); result = int_value(*c2.begin()); escape(&result); } BOOST_FALLTHROUGH; case 4: { clobber(); bc::segmented_swap_ranges(c2.begin(), c2.end(), c3.begin()); result = int_value(*c2.begin()); escape(&result); } BOOST_FALLTHROUGH; case 3: { clobber(); bc::segmented_swap_ranges(c2.begin(), c2.end(), c3.begin()); result = int_value(*c2.begin()); escape(&result); } BOOST_FALLTHROUGH; case 2: { clobber(); bc::segmented_swap_ranges(c2.begin(), c2.end(), c3.begin()); result = int_value(*c2.begin()); escape(&result); } BOOST_FALLTHROUGH; case 1: { clobber(); bc::segmented_swap_ranges(c2.begin(), c2.end(), c3.begin()); result = int_value(*c2.begin()); escape(&result); } if (BOOST_UNLIKELY(--n_ == 0)) { t2.stop(); break; } } while (true); } } double r1 = calc_ns_per_elem(t1.elapsed().wall, iters, c.size()); double r2 = calc_ns_per_elem(t2.elapsed().wall, iters, c.size()); print_ratio("swap_ranges", cname, r1, r2); } template void bench_search(const C &c, std::size_t iters, const char* cname, const typename C::value_type* pattern, std::size_t pat_size, const char* label) { typedef typename C::const_iterator cit_t; int result = 0; cpu_timer t1; { std::size_t n_ = (iters + 7) / 8; t1.resume(); switch (iters % 8) { case 0: do { { clobber(); cit_t it = std::search(c.begin(), c.end(), pattern, pattern + pat_size); result = (it == c.end()) ? 0 : 1; escape(&result); } BOOST_FALLTHROUGH; case 7: { clobber(); cit_t it = std::search(c.begin(), c.end(), pattern, pattern + pat_size); result = (it == c.end()) ? 0 : 1; escape(&result); } BOOST_FALLTHROUGH; case 6: { clobber(); cit_t it = std::search(c.begin(), c.end(), pattern, pattern + pat_size); result = (it == c.end()) ? 0 : 1; escape(&result); } BOOST_FALLTHROUGH; case 5: { clobber(); cit_t it = std::search(c.begin(), c.end(), pattern, pattern + pat_size); result = (it == c.end()) ? 0 : 1; escape(&result); } BOOST_FALLTHROUGH; case 4: { clobber(); cit_t it = std::search(c.begin(), c.end(), pattern, pattern + pat_size); result = (it == c.end()) ? 0 : 1; escape(&result); } BOOST_FALLTHROUGH; case 3: { clobber(); cit_t it = std::search(c.begin(), c.end(), pattern, pattern + pat_size); result = (it == c.end()) ? 0 : 1; escape(&result); } BOOST_FALLTHROUGH; case 2: { clobber(); cit_t it = std::search(c.begin(), c.end(), pattern, pattern + pat_size); result = (it == c.end()) ? 0 : 1; escape(&result); } BOOST_FALLTHROUGH; case 1: { clobber(); cit_t it = std::search(c.begin(), c.end(), pattern, pattern + pat_size); result = (it == c.end()) ? 0 : 1; escape(&result); } if (BOOST_UNLIKELY(--n_ == 0)) { t1.stop(); break; } } while (true); } } cpu_timer t2; { std::size_t n_ = (iters + 7) / 8; t2.resume(); switch (iters % 8) { case 0: do { { clobber(); cit_t it = bc::segmented_search(c.begin(), c.end(), pattern, pattern + pat_size); result = (it == c.end()) ? 0 : 1; escape(&result); } BOOST_FALLTHROUGH; case 7: { clobber(); cit_t it = bc::segmented_search(c.begin(), c.end(), pattern, pattern + pat_size); result = (it == c.end()) ? 0 : 1; escape(&result); } BOOST_FALLTHROUGH; case 6: { clobber(); cit_t it = bc::segmented_search(c.begin(), c.end(), pattern, pattern + pat_size); result = (it == c.end()) ? 0 : 1; escape(&result); } BOOST_FALLTHROUGH; case 5: { clobber(); cit_t it = bc::segmented_search(c.begin(), c.end(), pattern, pattern + pat_size); result = (it == c.end()) ? 0 : 1; escape(&result); } BOOST_FALLTHROUGH; case 4: { clobber(); cit_t it = bc::segmented_search(c.begin(), c.end(), pattern, pattern + pat_size); result = (it == c.end()) ? 0 : 1; escape(&result); } BOOST_FALLTHROUGH; case 3: { clobber(); cit_t it = bc::segmented_search(c.begin(), c.end(), pattern, pattern + pat_size); result = (it == c.end()) ? 0 : 1; escape(&result); } BOOST_FALLTHROUGH; case 2: { clobber(); cit_t it = bc::segmented_search(c.begin(), c.end(), pattern, pattern + pat_size); result = (it == c.end()) ? 0 : 1; escape(&result); } BOOST_FALLTHROUGH; case 1: { clobber(); cit_t it = bc::segmented_search(c.begin(), c.end(), pattern, pattern + pat_size); result = (it == c.end()) ? 0 : 1; escape(&result); } if (BOOST_UNLIKELY(--n_ == 0)) { t2.stop(); break; } } while (true); } } double r1 = calc_ns_per_elem(t1.elapsed().wall, iters, c.size()); double r2 = calc_ns_per_elem(t2.elapsed().wall, iters, c.size()); print_ratio(label, cname, r1, r2); } template void bench_search_n(const C &c, std::size_t iters, const char* cname, typename C::difference_type count, const typename C::value_type& val, const char* label) { typedef typename C::const_iterator cit_t; int result = 0; cpu_timer t1; { std::size_t n_ = (iters + 7) / 8; t1.resume(); switch (iters % 8) { case 0: do { { clobber(); cit_t it = std::search_n(c.begin(), c.end(), count, val); result = (it == c.end()) ? 0 : 1; escape(&result); } BOOST_FALLTHROUGH; case 7: { clobber(); cit_t it = std::search_n(c.begin(), c.end(), count, val); result = (it == c.end()) ? 0 : 1; escape(&result); } BOOST_FALLTHROUGH; case 6: { clobber(); cit_t it = std::search_n(c.begin(), c.end(), count, val); result = (it == c.end()) ? 0 : 1; escape(&result); } BOOST_FALLTHROUGH; case 5: { clobber(); cit_t it = std::search_n(c.begin(), c.end(), count, val); result = (it == c.end()) ? 0 : 1; escape(&result); } BOOST_FALLTHROUGH; case 4: { clobber(); cit_t it = std::search_n(c.begin(), c.end(), count, val); result = (it == c.end()) ? 0 : 1; escape(&result); } BOOST_FALLTHROUGH; case 3: { clobber(); cit_t it = std::search_n(c.begin(), c.end(), count, val); result = (it == c.end()) ? 0 : 1; escape(&result); } BOOST_FALLTHROUGH; case 2: { clobber(); cit_t it = std::search_n(c.begin(), c.end(), count, val); result = (it == c.end()) ? 0 : 1; escape(&result); } BOOST_FALLTHROUGH; case 1: { clobber(); cit_t it = std::search_n(c.begin(), c.end(), count, val); result = (it == c.end()) ? 0 : 1; escape(&result); } if (BOOST_UNLIKELY(--n_ == 0)) { t1.stop(); break; } } while (true); } } cpu_timer t2; { std::size_t n_ = (iters + 7) / 8; t2.resume(); switch (iters % 8) { case 0: do { { clobber(); cit_t it = bc::segmented_search_n(c.begin(), c.end(), count, val); result = (it == c.end()) ? 0 : 1; escape(&result); } BOOST_FALLTHROUGH; case 7: { clobber(); cit_t it = bc::segmented_search_n(c.begin(), c.end(), count, val); result = (it == c.end()) ? 0 : 1; escape(&result); } BOOST_FALLTHROUGH; case 6: { clobber(); cit_t it = bc::segmented_search_n(c.begin(), c.end(), count, val); result = (it == c.end()) ? 0 : 1; escape(&result); } BOOST_FALLTHROUGH; case 5: { clobber(); cit_t it = bc::segmented_search_n(c.begin(), c.end(), count, val); result = (it == c.end()) ? 0 : 1; escape(&result); } BOOST_FALLTHROUGH; case 4: { clobber(); cit_t it = bc::segmented_search_n(c.begin(), c.end(), count, val); result = (it == c.end()) ? 0 : 1; escape(&result); } BOOST_FALLTHROUGH; case 3: { clobber(); cit_t it = bc::segmented_search_n(c.begin(), c.end(), count, val); result = (it == c.end()) ? 0 : 1; escape(&result); } BOOST_FALLTHROUGH; case 2: { clobber(); cit_t it = bc::segmented_search_n(c.begin(), c.end(), count, val); result = (it == c.end()) ? 0 : 1; escape(&result); } BOOST_FALLTHROUGH; case 1: { clobber(); cit_t it = bc::segmented_search_n(c.begin(), c.end(), count, val); result = (it == c.end()) ? 0 : 1; escape(&result); } if (BOOST_UNLIKELY(--n_ == 0)) { t2.stop(); break; } } while (true); } } double r1 = calc_ns_per_elem(t1.elapsed().wall, iters, c.size()); double r2 = calc_ns_per_elem(t2.elapsed().wall, iters, c.size()); print_ratio(label, cname, r1, r2); } template void bench_set_union(const C &c, const C &c2, std::size_t iters, const char* cname) { typedef typename C::value_type VT; boost::container::vector out(c.size() + c2.size()); cpu_timer t1; { std::size_t n_ = (iters + 7) / 8; t1.resume(); switch (iters % 8) { case 0: do { { clobber(); std::set_union(c.begin(), c.end(), c2.begin(), c2.end(), out.begin()); escape(&out[0]); } BOOST_FALLTHROUGH; case 7: { clobber(); std::set_union(c.begin(), c.end(), c2.begin(), c2.end(), out.begin()); escape(&out[0]); } BOOST_FALLTHROUGH; case 6: { clobber(); std::set_union(c.begin(), c.end(), c2.begin(), c2.end(), out.begin()); escape(&out[0]); } BOOST_FALLTHROUGH; case 5: { clobber(); std::set_union(c.begin(), c.end(), c2.begin(), c2.end(), out.begin()); escape(&out[0]); } BOOST_FALLTHROUGH; case 4: { clobber(); std::set_union(c.begin(), c.end(), c2.begin(), c2.end(), out.begin()); escape(&out[0]); } BOOST_FALLTHROUGH; case 3: { clobber(); std::set_union(c.begin(), c.end(), c2.begin(), c2.end(), out.begin()); escape(&out[0]); } BOOST_FALLTHROUGH; case 2: { clobber(); std::set_union(c.begin(), c.end(), c2.begin(), c2.end(), out.begin()); escape(&out[0]); } BOOST_FALLTHROUGH; case 1: { clobber(); std::set_union(c.begin(), c.end(), c2.begin(), c2.end(), out.begin()); escape(&out[0]); } if (BOOST_UNLIKELY(--n_ == 0)) { t1.stop(); break; } } while (true); } } cpu_timer t2; { std::size_t n_ = (iters + 7) / 8; t2.resume(); switch (iters % 8) { case 0: do { { clobber(); bc::segmented_set_union(c.begin(), c.end(), c2.begin(), c2.end(), out.begin()); escape(&out[0]); } BOOST_FALLTHROUGH; case 7: { clobber(); bc::segmented_set_union(c.begin(), c.end(), c2.begin(), c2.end(), out.begin()); escape(&out[0]); } BOOST_FALLTHROUGH; case 6: { clobber(); bc::segmented_set_union(c.begin(), c.end(), c2.begin(), c2.end(), out.begin()); escape(&out[0]); } BOOST_FALLTHROUGH; case 5: { clobber(); bc::segmented_set_union(c.begin(), c.end(), c2.begin(), c2.end(), out.begin()); escape(&out[0]); } BOOST_FALLTHROUGH; case 4: { clobber(); bc::segmented_set_union(c.begin(), c.end(), c2.begin(), c2.end(), out.begin()); escape(&out[0]); } BOOST_FALLTHROUGH; case 3: { clobber(); bc::segmented_set_union(c.begin(), c.end(), c2.begin(), c2.end(), out.begin()); escape(&out[0]); } BOOST_FALLTHROUGH; case 2: { clobber(); bc::segmented_set_union(c.begin(), c.end(), c2.begin(), c2.end(), out.begin()); escape(&out[0]); } BOOST_FALLTHROUGH; case 1: { clobber(); bc::segmented_set_union(c.begin(), c.end(), c2.begin(), c2.end(), out.begin()); escape(&out[0]); } if (BOOST_UNLIKELY(--n_ == 0)) { t2.stop(); break; } } while (true); } } double r1 = calc_ns_per_elem(t1.elapsed().wall, iters, c.size()); double r2 = calc_ns_per_elem(t2.elapsed().wall, iters, c.size()); print_ratio("set_union", cname, r1, r2); } template void bench_set_difference(const C &c, const C &c2, std::size_t iters, const char* cname) { typedef typename C::value_type VT; boost::container::vector out(c.size()); cpu_timer t1; { std::size_t n_ = (iters + 7) / 8; t1.resume(); switch (iters % 8) { case 0: do { { clobber(); std::set_difference(c.begin(), c.end(), c2.begin(), c2.end(), out.begin()); escape(&out[0]); } BOOST_FALLTHROUGH; case 7: { clobber(); std::set_difference(c.begin(), c.end(), c2.begin(), c2.end(), out.begin()); escape(&out[0]); } BOOST_FALLTHROUGH; case 6: { clobber(); std::set_difference(c.begin(), c.end(), c2.begin(), c2.end(), out.begin()); escape(&out[0]); } BOOST_FALLTHROUGH; case 5: { clobber(); std::set_difference(c.begin(), c.end(), c2.begin(), c2.end(), out.begin()); escape(&out[0]); } BOOST_FALLTHROUGH; case 4: { clobber(); std::set_difference(c.begin(), c.end(), c2.begin(), c2.end(), out.begin()); escape(&out[0]); } BOOST_FALLTHROUGH; case 3: { clobber(); std::set_difference(c.begin(), c.end(), c2.begin(), c2.end(), out.begin()); escape(&out[0]); } BOOST_FALLTHROUGH; case 2: { clobber(); std::set_difference(c.begin(), c.end(), c2.begin(), c2.end(), out.begin()); escape(&out[0]); } BOOST_FALLTHROUGH; case 1: { clobber(); std::set_difference(c.begin(), c.end(), c2.begin(), c2.end(), out.begin()); escape(&out[0]); } if (BOOST_UNLIKELY(--n_ == 0)) { t1.stop(); break; } } while (true); } } cpu_timer t2; { std::size_t n_ = (iters + 7) / 8; t2.resume(); switch (iters % 8) { case 0: do { { clobber(); bc::segmented_set_difference(c.begin(), c.end(), c2.begin(), c2.end(), out.begin()); escape(&out[0]); } BOOST_FALLTHROUGH; case 7: { clobber(); bc::segmented_set_difference(c.begin(), c.end(), c2.begin(), c2.end(), out.begin()); escape(&out[0]); } BOOST_FALLTHROUGH; case 6: { clobber(); bc::segmented_set_difference(c.begin(), c.end(), c2.begin(), c2.end(), out.begin()); escape(&out[0]); } BOOST_FALLTHROUGH; case 5: { clobber(); bc::segmented_set_difference(c.begin(), c.end(), c2.begin(), c2.end(), out.begin()); escape(&out[0]); } BOOST_FALLTHROUGH; case 4: { clobber(); bc::segmented_set_difference(c.begin(), c.end(), c2.begin(), c2.end(), out.begin()); escape(&out[0]); } BOOST_FALLTHROUGH; case 3: { clobber(); bc::segmented_set_difference(c.begin(), c.end(), c2.begin(), c2.end(), out.begin()); escape(&out[0]); } BOOST_FALLTHROUGH; case 2: { clobber(); bc::segmented_set_difference(c.begin(), c.end(), c2.begin(), c2.end(), out.begin()); escape(&out[0]); } BOOST_FALLTHROUGH; case 1: { clobber(); bc::segmented_set_difference(c.begin(), c.end(), c2.begin(), c2.end(), out.begin()); escape(&out[0]); } if (BOOST_UNLIKELY(--n_ == 0)) { t2.stop(); break; } } while (true); } } double r1 = calc_ns_per_elem(t1.elapsed().wall, iters, c.size()); double r2 = calc_ns_per_elem(t2.elapsed().wall, iters, c.size()); print_ratio("set_difference", cname, r1, r2); } template void bench_set_intersection(const C &c, const C &c2, std::size_t iters, const char* cname) { typedef typename C::value_type VT; boost::container::vector out(c.size()); cpu_timer t1; { std::size_t n_ = (iters + 7) / 8; t1.resume(); switch (iters % 8) { case 0: do { { clobber(); std::set_intersection(c.begin(), c.end(), c2.begin(), c2.end(), out.begin()); escape(&out[0]); } BOOST_FALLTHROUGH; case 7: { clobber(); std::set_intersection(c.begin(), c.end(), c2.begin(), c2.end(), out.begin()); escape(&out[0]); } BOOST_FALLTHROUGH; case 6: { clobber(); std::set_intersection(c.begin(), c.end(), c2.begin(), c2.end(), out.begin()); escape(&out[0]); } BOOST_FALLTHROUGH; case 5: { clobber(); std::set_intersection(c.begin(), c.end(), c2.begin(), c2.end(), out.begin()); escape(&out[0]); } BOOST_FALLTHROUGH; case 4: { clobber(); std::set_intersection(c.begin(), c.end(), c2.begin(), c2.end(), out.begin()); escape(&out[0]); } BOOST_FALLTHROUGH; case 3: { clobber(); std::set_intersection(c.begin(), c.end(), c2.begin(), c2.end(), out.begin()); escape(&out[0]); } BOOST_FALLTHROUGH; case 2: { clobber(); std::set_intersection(c.begin(), c.end(), c2.begin(), c2.end(), out.begin()); escape(&out[0]); } BOOST_FALLTHROUGH; case 1: { clobber(); std::set_intersection(c.begin(), c.end(), c2.begin(), c2.end(), out.begin()); escape(&out[0]); } if (BOOST_UNLIKELY(--n_ == 0)) { t1.stop(); break; } } while (true); } } cpu_timer t2; { std::size_t n_ = (iters + 7) / 8; t2.resume(); switch (iters % 8) { case 0: do { { clobber(); bc::segmented_set_intersection(c.begin(), c.end(), c2.begin(), c2.end(), out.begin()); escape(&out[0]); } BOOST_FALLTHROUGH; case 7: { clobber(); bc::segmented_set_intersection(c.begin(), c.end(), c2.begin(), c2.end(), out.begin()); escape(&out[0]); } BOOST_FALLTHROUGH; case 6: { clobber(); bc::segmented_set_intersection(c.begin(), c.end(), c2.begin(), c2.end(), out.begin()); escape(&out[0]); } BOOST_FALLTHROUGH; case 5: { clobber(); bc::segmented_set_intersection(c.begin(), c.end(), c2.begin(), c2.end(), out.begin()); escape(&out[0]); } BOOST_FALLTHROUGH; case 4: { clobber(); bc::segmented_set_intersection(c.begin(), c.end(), c2.begin(), c2.end(), out.begin()); escape(&out[0]); } BOOST_FALLTHROUGH; case 3: { clobber(); bc::segmented_set_intersection(c.begin(), c.end(), c2.begin(), c2.end(), out.begin()); escape(&out[0]); } BOOST_FALLTHROUGH; case 2: { clobber(); bc::segmented_set_intersection(c.begin(), c.end(), c2.begin(), c2.end(), out.begin()); escape(&out[0]); } BOOST_FALLTHROUGH; case 1: { clobber(); bc::segmented_set_intersection(c.begin(), c.end(), c2.begin(), c2.end(), out.begin()); escape(&out[0]); } if (BOOST_UNLIKELY(--n_ == 0)) { t2.stop(); break; } } while (true); } } double r1 = calc_ns_per_elem(t1.elapsed().wall, iters, c.size()); double r2 = calc_ns_per_elem(t2.elapsed().wall, iters, c.size()); print_ratio("set_intersection", cname, r1, r2); } template void bench_set_symmetric_difference(const C &c, const C &c2, std::size_t iters, const char* cname) { typedef typename C::value_type VT; boost::container::vector out(c.size() + c2.size()); cpu_timer t1; { std::size_t n_ = (iters + 7) / 8; t1.resume(); switch (iters % 8) { case 0: do { { clobber(); std::set_symmetric_difference(c.begin(), c.end(), c2.begin(), c2.end(), out.begin()); escape(&out[0]); } BOOST_FALLTHROUGH; case 7: { clobber(); std::set_symmetric_difference(c.begin(), c.end(), c2.begin(), c2.end(), out.begin()); escape(&out[0]); } BOOST_FALLTHROUGH; case 6: { clobber(); std::set_symmetric_difference(c.begin(), c.end(), c2.begin(), c2.end(), out.begin()); escape(&out[0]); } BOOST_FALLTHROUGH; case 5: { clobber(); std::set_symmetric_difference(c.begin(), c.end(), c2.begin(), c2.end(), out.begin()); escape(&out[0]); } BOOST_FALLTHROUGH; case 4: { clobber(); std::set_symmetric_difference(c.begin(), c.end(), c2.begin(), c2.end(), out.begin()); escape(&out[0]); } BOOST_FALLTHROUGH; case 3: { clobber(); std::set_symmetric_difference(c.begin(), c.end(), c2.begin(), c2.end(), out.begin()); escape(&out[0]); } BOOST_FALLTHROUGH; case 2: { clobber(); std::set_symmetric_difference(c.begin(), c.end(), c2.begin(), c2.end(), out.begin()); escape(&out[0]); } BOOST_FALLTHROUGH; case 1: { clobber(); std::set_symmetric_difference(c.begin(), c.end(), c2.begin(), c2.end(), out.begin()); escape(&out[0]); } if (BOOST_UNLIKELY(--n_ == 0)) { t1.stop(); break; } } while (true); } } cpu_timer t2; { std::size_t n_ = (iters + 7) / 8; t2.resume(); switch (iters % 8) { case 0: do { { clobber(); bc::segmented_set_symmetric_difference(c.begin(), c.end(), c2.begin(), c2.end(), out.begin()); escape(&out[0]); } BOOST_FALLTHROUGH; case 7: { clobber(); bc::segmented_set_symmetric_difference(c.begin(), c.end(), c2.begin(), c2.end(), out.begin()); escape(&out[0]); } BOOST_FALLTHROUGH; case 6: { clobber(); bc::segmented_set_symmetric_difference(c.begin(), c.end(), c2.begin(), c2.end(), out.begin()); escape(&out[0]); } BOOST_FALLTHROUGH; case 5: { clobber(); bc::segmented_set_symmetric_difference(c.begin(), c.end(), c2.begin(), c2.end(), out.begin()); escape(&out[0]); } BOOST_FALLTHROUGH; case 4: { clobber(); bc::segmented_set_symmetric_difference(c.begin(), c.end(), c2.begin(), c2.end(), out.begin()); escape(&out[0]); } BOOST_FALLTHROUGH; case 3: { clobber(); bc::segmented_set_symmetric_difference(c.begin(), c.end(), c2.begin(), c2.end(), out.begin()); escape(&out[0]); } BOOST_FALLTHROUGH; case 2: { clobber(); bc::segmented_set_symmetric_difference(c.begin(), c.end(), c2.begin(), c2.end(), out.begin()); escape(&out[0]); } BOOST_FALLTHROUGH; case 1: { clobber(); bc::segmented_set_symmetric_difference(c.begin(), c.end(), c2.begin(), c2.end(), out.begin()); escape(&out[0]); } if (BOOST_UNLIKELY(--n_ == 0)) { t2.stop(); break; } } while (true); } } double r1 = calc_ns_per_elem(t1.elapsed().wall, iters, c.size()); double r2 = calc_ns_per_elem(t2.elapsed().wall, iters, c.size()); print_ratio("set_symmetric_difference", cname, r1, r2); } template void bench_partition(const C &c, std::size_t iters, const char* cname, Pred pred, const char* label) { typedef typename C::iterator it_t; int result = 0; cpu_timer t1; { C c1(c), c2(c), c3(c), c4(c), c5(c), c6(c), c7(c), c8(c); std::size_t n_ = (iters + 7) / 8; t1.resume(); switch (iters % 8) { case 0: do { t1.resume(); { clobber(); it_t it = std::partition(c1.begin(), c1.end(), pred); result = (it == c1.end()) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 7: { clobber(); it_t it = std::partition(c2.begin(), c2.end(), pred); result = (it == c2.end()) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 6: { clobber(); it_t it = std::partition(c3.begin(), c3.end(), pred); result = (it == c3.end()) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 5: { clobber(); it_t it = std::partition(c4.begin(), c4.end(), pred); result = (it == c4.end()) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 4: { clobber(); it_t it = std::partition(c5.begin(), c5.end(), pred); result = (it == c5.end()) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 3: { clobber(); it_t it = std::partition(c6.begin(), c6.end(), pred); result = (it == c6.end()) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 2: { clobber(); it_t it = std::partition(c7.begin(), c7.end(), pred); result = (it == c7.end()) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 1: { clobber(); it_t it = std::partition(c8.begin(), c8.end(), pred); result = (it == c8.end()) ? 1 : 0; escape(&result); } t1.stop(); if (BOOST_UNLIKELY(--n_ == 0)) { break; } c1 = c2 = c3 = c4 = c5 = c6 = c7 = c8 = c; } while (true); } } cpu_timer t2; { C c1(c), c2(c), c3(c), c4(c), c5(c), c6(c), c7(c), c8(c); std::size_t n_ = (iters + 7) / 8; t2.resume(); switch (iters % 8) { case 0: do { t2.resume(); { clobber(); it_t it = bc::segmented_partition(c1.begin(), c1.end(), pred); result = (it == c1.end()) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 7: { clobber(); it_t it = bc::segmented_partition(c2.begin(), c2.end(), pred); result = (it == c2.end()) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 6: { clobber(); it_t it = bc::segmented_partition(c3.begin(), c3.end(), pred); result = (it == c3.end()) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 5: { clobber(); it_t it = bc::segmented_partition(c4.begin(), c4.end(), pred); result = (it == c4.end()) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 4: { clobber(); it_t it = bc::segmented_partition(c5.begin(), c5.end(), pred); result = (it == c5.end()) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 3: { clobber(); it_t it = bc::segmented_partition(c6.begin(), c6.end(), pred); result = (it == c6.end()) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 2: { clobber(); it_t it = bc::segmented_partition(c7.begin(), c7.end(), pred); result = (it == c7.end()) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 1: { clobber(); it_t it = bc::segmented_partition(c8.begin(), c8.end(), pred); result = (it == c8.end()) ? 1 : 0; escape(&result); } t2.stop(); if (BOOST_UNLIKELY(--n_ == 0)) { break; } c1 = c2 = c3 = c4 = c5 = c6 = c7 = c8 = c; } while (true); } } double r1 = calc_ns_per_elem(t1.elapsed().wall, iters, c.size()); double r2 = calc_ns_per_elem(t2.elapsed().wall, iters, c.size()); print_ratio(label, cname, r1, r2); } template void bench_stable_partition(const C &c, std::size_t iters, const char* cname, Pred pred, const char* label) { typedef typename C::iterator it_t; int result = 0; cpu_timer t1; { C c1(c), c2(c), c3(c), c4(c), c5(c), c6(c), c7(c), c8(c); std::size_t n_ = (iters + 7) / 8; t1.resume(); switch (iters % 8) { case 0: do { t1.resume(); { clobber(); it_t it = std::stable_partition(c1.begin(), c1.end(), pred); result = (it == c1.end()) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 7: { clobber(); it_t it = std::stable_partition(c2.begin(), c2.end(), pred); result = (it == c2.end()) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 6: { clobber(); it_t it = std::stable_partition(c3.begin(), c3.end(), pred); result = (it == c3.end()) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 5: { clobber(); it_t it = std::stable_partition(c4.begin(), c4.end(), pred); result = (it == c4.end()) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 4: { clobber(); it_t it = std::stable_partition(c5.begin(), c5.end(), pred); result = (it == c5.end()) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 3: { clobber(); it_t it = std::stable_partition(c6.begin(), c6.end(), pred); result = (it == c6.end()) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 2: { clobber(); it_t it = std::stable_partition(c7.begin(), c7.end(), pred); result = (it == c7.end()) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 1: { clobber(); it_t it = std::stable_partition(c8.begin(), c8.end(), pred); result = (it == c8.end()) ? 1 : 0; escape(&result); } t1.stop(); if (BOOST_UNLIKELY(--n_ == 0)) { break; } c1 = c2 = c3 = c4 = c5 = c6 = c7 = c8 = c; } while (true); } } cpu_timer t2; { C c1(c), c2(c), c3(c), c4(c), c5(c), c6(c), c7(c), c8(c); std::size_t n_ = (iters + 7) / 8; t2.resume(); switch (iters % 8) { case 0: do { t2.resume(); { clobber(); it_t it = bc::segmented_stable_partition(c1.begin(), c1.end(), pred); result = (it == c1.end()) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 7: { clobber(); it_t it = bc::segmented_stable_partition(c2.begin(), c2.end(), pred); result = (it == c2.end()) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 6: { clobber(); it_t it = bc::segmented_stable_partition(c3.begin(), c3.end(), pred); result = (it == c3.end()) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 5: { clobber(); it_t it = bc::segmented_stable_partition(c4.begin(), c4.end(), pred); result = (it == c4.end()) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 4: { clobber(); it_t it = bc::segmented_stable_partition(c5.begin(), c5.end(), pred); result = (it == c5.end()) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 3: { clobber(); it_t it = bc::segmented_stable_partition(c6.begin(), c6.end(), pred); result = (it == c6.end()) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 2: { clobber(); it_t it = bc::segmented_stable_partition(c7.begin(), c7.end(), pred); result = (it == c7.end()) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 1: { clobber(); it_t it = bc::segmented_stable_partition(c8.begin(), c8.end(), pred); result = (it == c8.end()) ? 1 : 0; escape(&result); } t2.stop(); if (BOOST_UNLIKELY(--n_ == 0)) { break; } c1 = c2 = c3 = c4 = c5 = c6 = c7 = c8 = c; } while (true); } } double r1 = calc_ns_per_elem(t1.elapsed().wall, iters, c.size()); double r2 = calc_ns_per_elem(t2.elapsed().wall, iters, c.size()); print_ratio(label, cname, r1, r2); } template void bench_partition_copy(const C &c, std::size_t iters, const char* cname) { typedef typename C::value_type VT; boost::container::vector t_out(c.size()); boost::container::vector f_out(c.size()); cpu_timer t1; { std::size_t n_ = (iters + 7) / 8; t1.resume(); switch (iters % 8) { case 0: do { { clobber(); bench_detail::partition_copy(c.begin(), c.end(), t_out.begin(), f_out.begin(), is_odd()); escape(&t_out[0]); } BOOST_FALLTHROUGH; case 7: { clobber(); bench_detail::partition_copy(c.begin(), c.end(), t_out.begin(), f_out.begin(), is_odd()); escape(&t_out[0]); } BOOST_FALLTHROUGH; case 6: { clobber(); bench_detail::partition_copy(c.begin(), c.end(), t_out.begin(), f_out.begin(), is_odd()); escape(&t_out[0]); } BOOST_FALLTHROUGH; case 5: { clobber(); bench_detail::partition_copy(c.begin(), c.end(), t_out.begin(), f_out.begin(), is_odd()); escape(&t_out[0]); } BOOST_FALLTHROUGH; case 4: { clobber(); bench_detail::partition_copy(c.begin(), c.end(), t_out.begin(), f_out.begin(), is_odd()); escape(&t_out[0]); } BOOST_FALLTHROUGH; case 3: { clobber(); bench_detail::partition_copy(c.begin(), c.end(), t_out.begin(), f_out.begin(), is_odd()); escape(&t_out[0]); } BOOST_FALLTHROUGH; case 2: { clobber(); bench_detail::partition_copy(c.begin(), c.end(), t_out.begin(), f_out.begin(), is_odd()); escape(&t_out[0]); } BOOST_FALLTHROUGH; case 1: { clobber(); bench_detail::partition_copy(c.begin(), c.end(), t_out.begin(), f_out.begin(), is_odd()); escape(&t_out[0]); } if (BOOST_UNLIKELY(--n_ == 0)) { t1.stop(); break; } } while (true); } } cpu_timer t2; { std::size_t n_ = (iters + 7) / 8; t2.resume(); switch (iters % 8) { case 0: do { { clobber(); bc::segmented_partition_copy(c.begin(), c.end(), t_out.begin(), f_out.begin(), is_odd()); escape(&t_out[0]); } BOOST_FALLTHROUGH; case 7: { clobber(); bc::segmented_partition_copy(c.begin(), c.end(), t_out.begin(), f_out.begin(), is_odd()); escape(&t_out[0]); } BOOST_FALLTHROUGH; case 6: { clobber(); bc::segmented_partition_copy(c.begin(), c.end(), t_out.begin(), f_out.begin(), is_odd()); escape(&t_out[0]); } BOOST_FALLTHROUGH; case 5: { clobber(); bc::segmented_partition_copy(c.begin(), c.end(), t_out.begin(), f_out.begin(), is_odd()); escape(&t_out[0]); } BOOST_FALLTHROUGH; case 4: { clobber(); bc::segmented_partition_copy(c.begin(), c.end(), t_out.begin(), f_out.begin(), is_odd()); escape(&t_out[0]); } BOOST_FALLTHROUGH; case 3: { clobber(); bc::segmented_partition_copy(c.begin(), c.end(), t_out.begin(), f_out.begin(), is_odd()); escape(&t_out[0]); } BOOST_FALLTHROUGH; case 2: { clobber(); bc::segmented_partition_copy(c.begin(), c.end(), t_out.begin(), f_out.begin(), is_odd()); escape(&t_out[0]); } BOOST_FALLTHROUGH; case 1: { clobber(); bc::segmented_partition_copy(c.begin(), c.end(), t_out.begin(), f_out.begin(), is_odd()); escape(&t_out[0]); } if (BOOST_UNLIKELY(--n_ == 0)) { t2.stop(); break; } } while (true); } } double r1 = calc_ns_per_elem(t1.elapsed().wall, iters, c.size()); double r2 = calc_ns_per_elem(t2.elapsed().wall, iters, c.size()); print_ratio("partition_copy", cname, r1, r2); } template void bench_partition_point(const C &c, std::size_t iters, const char* cname, Pred pred, const char* label) { typedef typename C::const_iterator cit_t; int result = 0; cpu_timer t1; { std::size_t n_ = (iters + 7) / 8; t1.resume(); switch (iters % 8) { case 0: do { { clobber(); cit_t it = bench_detail::partition_point(c.begin(), c.end(), pred); result = (it == c.end()) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 7: { clobber(); cit_t it = bench_detail::partition_point(c.begin(), c.end(), pred); result = (it == c.end()) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 6: { clobber(); cit_t it = bench_detail::partition_point(c.begin(), c.end(), pred); result = (it == c.end()) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 5: { clobber(); cit_t it = bench_detail::partition_point(c.begin(), c.end(), pred); result = (it == c.end()) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 4: { clobber(); cit_t it = bench_detail::partition_point(c.begin(), c.end(), pred); result = (it == c.end()) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 3: { clobber(); cit_t it = bench_detail::partition_point(c.begin(), c.end(), pred); result = (it == c.end()) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 2: { clobber(); cit_t it = bench_detail::partition_point(c.begin(), c.end(), pred); result = (it == c.end()) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 1: { clobber(); cit_t it = bench_detail::partition_point(c.begin(), c.end(), pred); result = (it == c.end()) ? 1 : 0; escape(&result); } if (BOOST_UNLIKELY(--n_ == 0)) { t1.stop(); break; } } while (true); } } cpu_timer t2; { std::size_t n_ = (iters + 7) / 8; t2.resume(); switch (iters % 8) { case 0: do { { clobber(); cit_t it = bc::segmented_partition_point(c.begin(), c.end(), pred); result = (it == c.end()) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 7: { clobber(); cit_t it = bc::segmented_partition_point(c.begin(), c.end(), pred); result = (it == c.end()) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 6: { clobber(); cit_t it = bc::segmented_partition_point(c.begin(), c.end(), pred); result = (it == c.end()) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 5: { clobber(); cit_t it = bc::segmented_partition_point(c.begin(), c.end(), pred); result = (it == c.end()) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 4: { clobber(); cit_t it = bc::segmented_partition_point(c.begin(), c.end(), pred); result = (it == c.end()) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 3: { clobber(); cit_t it = bc::segmented_partition_point(c.begin(), c.end(), pred); result = (it == c.end()) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 2: { clobber(); cit_t it = bc::segmented_partition_point(c.begin(), c.end(), pred); result = (it == c.end()) ? 1 : 0; escape(&result); } BOOST_FALLTHROUGH; case 1: { clobber(); cit_t it = bc::segmented_partition_point(c.begin(), c.end(), pred); result = (it == c.end()) ? 1 : 0; escape(&result); } if (BOOST_UNLIKELY(--n_ == 0)) { t2.stop(); break; } } while (true); } } double r1 = calc_ns_per_elem(t1.elapsed().wall, iters, c.size()); double r2 = calc_ns_per_elem(t2.elapsed().wall, iters, c.size()); print_ratio(label, cname, r1, r2); } ////////////////////////////////////////////////////////////////////////////// // Run all benchmarks for a container type ////////////////////////////////////////////////////////////////////////////// template void run_all(const C& c, std::size_t iters, const char* cname) { typedef typename C::value_type VT; const VT zero(0); const VT min1(-1); const VT quart((int)c.size()/4); const VT half((int)c.size()/2); const VT threequart((int)c.size()*3/4); g_geomean.reset(); print_subheader(); //all_of bench_all_of(c, iters, cname, is_zero_or_positive(), "all_of(hit)"); bench_all_of(c, iters, cname, unequal_to_ref(half), "all_of(miss)"); //any_of bench_any_of(c, iters, cname, equal_to_ref(half), "any_of(hit)"); bench_any_of(c, iters, cname, is_negative(), "any_of(miss)"); //copy bench_copy(c, iters, cname, "copy"); bench_copy(c, iters, cname, "copy(2xS)"); //copy_if bench_copy_if(c, iters, cname, is_odd(), "copy_if(hit)"); bench_copy_if(c, iters, cname, is_negative(), "copy_if(miss)"); //copy_n bench_copy_n(c, iters, cname); //count bench_count(c, iters, cname, zero, "count(hit)"); bench_count(c, iters, cname, min1, "count(miss)"); //count_if bench_count_if(c, iters, cname, is_odd(), "count_if(hit)"); bench_count_if(c, iters, cname, is_negative(), "count_if(miss)"); //equal { C c2(c); bench_equal(c, c2, iters, cname, "equal(hit)"); *boost::container::make_iterator_uadvance(c2.begin(), c2.size()/2) = min1; bench_equal(c, c2, iters, cname, "equal(miss)"); } //fill bench_fill(c, iters, cname); //fill_n bench_fill_n(c, iters, cname); //find bench_find(c, iters, cname, half, "find(hit)"); bench_find(c, iters, cname, min1, "find(miss)"); //find_if bench_find_if(c, iters, cname, equal_to_ref(half), "find_if(hit)"); bench_find_if(c, iters, cname, is_negative(), "find_if(miss)"); //find_if_not bench_find_if_not(c, iters, cname, unequal_to_ref(half), "find_if_not(hit)"); bench_find_if_not(c, iters, cname, is_zero_or_positive(), "find_if_not(miss)"); //find_last bench_find_last(c, iters, cname, half, "find_last(hit)"); bench_find_last(c, iters, cname, min1, "find_last(miss)"); //find_last_if bench_find_last_if(c, iters, cname, equal_to_ref(half), "find_last_if(hit)"); bench_find_last_if(c, iters, cname, is_negative(), "find_last_if(miss)"); //find_last_if_not bench_find_last_if_not(c, iters, cname, unequal_to_ref(half), "find_last_if_not(hit)"); bench_find_last_if_not(c, iters, cname, is_zero_or_positive(), "find_last_if_not(miss)"); //for_each bench_for_each(c, iters, cname); //generate bench_generate(c, iters, cname); //generate_n bench_generate_n(c, iters, cname); //is_partitioned { bench_is_partitioned(c, iters, cname, is_negative(), "is_partitioned(hit)"); C c2(c); *boost::container::make_iterator_uadvance(c2.begin(), c2.size()/2) = min1; bench_is_partitioned(c2, iters, cname, is_negative(), "is_partitioned(miss)"); } //is_sorted { bench_is_sorted(c, iters, cname, "is_sorted(hit)"); C c2(c); *boost::container::make_iterator_uadvance(c2.begin(), c2.size()/2) = min1; bench_is_sorted(c2, iters, cname, "is_sorted(miss)"); } //is_sorted_until { bench_is_sorted_until(c, iters, cname, "is_sorted_until(hit)"); C c2(c); *boost::container::make_iterator_uadvance(c2.begin(), c2.size()/2) = min1; bench_is_sorted_until(c2, iters, cname, "is_sorted_until(miss)"); } //merge { C c2(c); for (typename C::iterator it = c2.begin(); it != c2.end(); ++it) *it = VT(int_value(*it) * 2); bench_merge(c, c2, iters, cname); } //mismatch { C c2(c); *boost::container::make_iterator_uadvance(c2.begin(), c2.size()/2) = min1; bench_mismatch(c, c2, iters, cname, "mismatch(hit)"); *boost::container::make_iterator_uadvance(c2.begin(), c2.size()/2) = *boost::container::make_iterator_uadvance(c.begin(), c.size()/2); bench_mismatch(c, c2, iters, cname, "mismatch(miss)"); } //none_of bench_none_of(c, iters, cname, is_negative(), "none_of(hit)"); bench_none_of(c, iters, cname, equal_to_ref(VT(static_cast(c.size()/2))), "none_of(miss)"); bench_partition(c, iters, cname, is_odd(), "partition(hit)"); bench_partition(c, iters, cname, is_negative(), "partition(miss)"); //partition_copy bench_partition_copy(c, iters, cname); //partition_point (not tested since it's not optimized for random access iterators) //bench_partition_point(c, iters, cname, less_than_ref(static_cast((int)c.size()/2)), "partition_point(hit)"); //bench_partition_point(c, iters, cname, is_zero_or_positive(), "partition_point(miss)"); //remove bench_remove(c, iters, cname, half, "remove(hit)"); bench_remove(c, iters, cname, min1, "remove(miss)"); //remove_copy bench_remove_copy(c, iters, cname, half, "remove_copy(hit)"); bench_remove_copy(c, iters, cname, half, "remove_copy(2xS hit)"); bench_remove_copy(c, iters, cname, min1, "remove_copy(miss)"); bench_remove_copy(c, iters, cname, min1, "remove_copy(2xS miss)"); //remove_copy_if bench_remove_copy_if(c, iters, cname, less_and_greater_ref(quart, threequart), "remove_copy_if(hit)"); bench_remove_copy_if(c, iters, cname, less_and_greater_ref(quart, threequart), "remove_copy_if(2xS hit)"); bench_remove_copy_if(c, iters, cname, is_negative(), "remove_copy_if(miss)"); bench_remove_copy_if(c, iters, cname, is_negative(), "remove_copy_if(2xS miss)"); //remove_if bench_remove_if(c, iters, cname, less_and_greater_ref(quart, threequart), "remove_if(hit)"); bench_remove_if(c, iters, cname, is_negative(), "remove_if(miss)"); //replace { //Replace half of the elements to ensure that the "hit" case is not too fast C c2(c); is_odd is_odd_pred; for (typename C::iterator it = c2.begin(); it != c2.end(); ++it){ if( is_odd_pred(*it) ) *it = min1; } bench_replace(c2, iters, cname, min1, VT(-2), "replace(hit)"); } bench_replace(c, iters, cname, min1, VT(-2), "replace(miss)"); //replace_if bench_replace_if(c, iters, cname, is_odd(), VT(-2), "replace_if(hit)"); bench_replace_if(c, iters, cname, is_negative(), VT(-2), "replace_if(miss)"); //reverse bench_reverse(c, iters, cname); //reverse_copy bench_reverse_copy(c, iters, cname); //search { int ihalf = static_cast(c.size() / 2); VT hit_pat[] = {half, VT(ihalf + 1), VT(ihalf + 2)}; bench_search(c, iters, cname, hit_pat, 3, "search(hit)"); VT miss_pat[] = {min1, VT(-2), VT(-3)}; bench_search(c, iters, cname, miss_pat, 3, "search(miss)"); } //search_n bench_search_n(c, iters, cname, 1, half, "search_n(hit)"); bench_search_n(c, iters, cname, 3, min1, "search_n(miss)"); //set_difference, set_symmetric_difference, set_union { C c2(c); for (typename C::iterator it = c2.begin(); it != c2.end(); ++it) *it = VT(int_value(*it) * 2); bench_set_difference(c, c2, iters, cname); bench_set_intersection(c, c2, iters, cname); bench_set_symmetric_difference(c, c2, iters, cname); bench_set_union(c, c2, iters, cname); } //stable_partition (not tested since it's not optimized for random access iterators) //bench_stable_partition(c, iters, cname, is_odd(), "stable_partition(hit)"); //bench_stable_partition(c, iters, cname, is_negative(), "stable_partition(miss)"); //swap_ranges bench_swap_ranges(c, iters, cname); //transform bench_transform(c, iters, cname); std::cout << '\n' << std::left << std::setw(32) << "GEOMEAN" << std::right << std::setw(20) << std::fixed << std::setprecision(2) << g_geomean.result() << "x\n"; } ////////////////////////////////////////////////////////////////////////////// // Run all benchmarks for a given value type ////////////////////////////////////////////////////////////////////////////// template void run_benchmarks() { //#define SIMPLE_TEST #if defined(NDEBUG) && !defined(SIMPLE_TEST) const std::size_t N = 100000; const std::size_t iter = 2000; #else const std::size_t N = 10000; const std::size_t iter = 1; #endif std::cout << "\n=== Segmented algorithm benchmark [" << typeid(T).name() << "] ===\n" << "Elements: " << N << " Iterations: " << iter << "\n\n"; { std::cout << "--- bc::deque<" << typeid(T).name() << "> ---\n"; bc::deque dq; fill_test_data(dq, N); run_all(dq, iter, "deque"); std::cout << "\n"; }/* { std::cout << "--- bc::nest<" << typeid(T).name() << "> ---\n"; bc::nest nt; fill_test_data(nt, N); run_all(nt, iter, "nest"); std::cout << "\n"; }*/ } ////////////////////////////////////////////////////////////////////////////// // Main ////////////////////////////////////////////////////////////////////////////// int main() { //run_benchmarks(); run_benchmarks(); //run_benchmarks(); return 0; }