////////////////////////////////////////////////////////////////////////////// // // (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 #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; #ifdef TASK_POOL typedef boost::tp::task< pool_type, void > task_type; #else typedef boost::tp::task< void > task_type; #endif template < typename DirectSolver, typename Composer, typename AE, typename Range > void inplace_solve( AE & ae, boost::iterator_range::type> range, unsigned cutoff ); template < typename DirectSolver, typename Composer, typename AE, typename Range > void inplace_solve( AE & ae, boost::iterator_range::type> range, unsigned cutoff ) { unsigned size = boost::size(range); //std::cout << "< parts(range, BOOST_PARTS); std::list tasks; #if 0 // this code do not compiles with gcc 3.4.4 cygwin boost::transform(parts, boost::begin(tasks), boost::bind(&AE::submit, boost::ref(ae), //boost::bind(&boost::interthreads::fork, boost::ref(ae), boost::bind(&inplace_solve, boost::ref(ae),_1,cutoff))); #else 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.push_back(tmp); } #endif inplace_solve(ae, parts[BOOST_PARTS-1], cutoff); boost::for_each(tasks, &boost::interthreads::wait_act); //std::cout << "par_inplace_merge_fct " << size << ">>"<< std::endl; Composer()(range); //std::cout << "par_ " << size << ">>"<< std::endl; } } 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(AE& ae, Range& range, unsigned cutoff=10000) { boost::iterator_range::type> rng(range); inplace_solve( ae, 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