////////////////////////////////////////////////////////////////////////////// // // (C) Copyright Vicente J. Botet Escriba 2008-2009. // 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/interthreads for documentation. // // Based on the shared.cpp example from the threadalert library of Roland Schwarz ////////////////////////////////////////////////////////////////////////////// #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define BOOST_PARTS 2 #define NN 400000 class scoped_timer { boost::posix_time::ptime start_; public: scoped_timer() : start_(boost::posix_time::microsec_clock::universal_time()) {} ~scoped_timer() { boost::posix_time::ptime stop( boost::posix_time::microsec_clock::universal_time() ); std::cout << " " << ( stop - start_).total_milliseconds() << " milli seconds" << std::endl; } }; template class partition { public: boost::iterator_range::type> range_; std::size_t parts_; partition(boost::iterator_range::type>& range, std::size_t parts): range_(range), parts_(parts) {} boost::iterator_range::type> operator[](unsigned i) { unsigned size = boost::size(range_); if (i<(parts_-1)) return boost::make_sliced_range(range_, i*(size/parts_), ((i+1)*(size/parts_))); else return boost::make_sliced_range(range_, (parts_-1)*(size/parts_), size); } }; typedef boost::tp::pool< boost::tp::unbounded_channel< boost::tp::fifo > > pool_type; typedef boost::tp::task< void > task_type; template < typename DirectSolver, typename Composer, typename AE, typename Range > void inplace_solve( AE & ae, boost::sub_range range, unsigned cutoff ); template < typename DirectSolver, typename Composer, typename AE, typename Range > void inplace_solve( AE & ae, boost::sub_range range, unsigned cutoff) { unsigned size = boost::size(range); if ( size <= cutoff) DirectSolver()(range); else { partition parts(range, BOOST_PARTS); task_type tasks[BOOST_PARTS]; for (unsigned i=0;i < BOOST_PARTS-1; ++i) { task_type tmp(ae.submit( boost::bind( &inplace_solve, boost::ref(ae), parts[i], cutoff ))); tasks[i] = tmp; } inplace_solve(ae, parts[BOOST_PARTS-1], cutoff); for (unsigned i=0;i < BOOST_PARTS-1; ++i) { tasks[i].wait(); }; Composer()(range); } } struct sort_fct { template RandomAccessRange& operator()(RandomAccessRange rng) { return boost::sort(rng); } }; struct inplace_merge_fct { template BidirectionalRange& operator()( BidirectionalRange rng) { return boost::inplace_merge(rng, boost::begin(rng)+(boost::size(rng)/2)); } }; template void parallel_sort(Range& range, unsigned cutoff=10000) { pool_type pool( boost::tp::poolsize( 2) ); // pool_type& pool(boost::this_task::get_thread_pool() ); boost::sub_range rng(boost::begin(range), boost::end(range)); inplace_solve( pool, rng, cutoff); } int sorted[NN]; int values1[NN]; int values2[NN]; int values3[NN]; int values4[NN]; int values5[NN]; int values6[NN]; int main() { for (unsigned i=0; i