1.         #include <iostream> 
 2.         #include <algorithm> 
 3.         #include <vector> 
 4.         #include <list> 
 5.         #include <math.h> 
 6.         #include <tbb/task_scheduler_init.h> 
 7.         #include <tbb/blocked_range.h> 
 8.         #include <tbb/parallel_for.h> 
 9.         #include <tbb/pipeline.h> 
 10.     #include <tbb/tick_count.h> 
 11.      
 12.      
 13.      
 14.      
 15.     template<class _Cat1, class _Cat2> 
 16.     struct both_random_helper{ 
 17.         typedef std::forward_iterator_tag Iter_cat; 
 18.     }; 
 19.     template<> 
 20.     struct both_random_helper< 
 21.         std::random_access_iterator_tag, 
 22.         std::random_access_iterator_tag>{ 
 23.         typedef std::random_access_iterator_tag Iter_cat; 
 24.     }; 
 25.      
 26.     template<class _InIt, class _OutIt> 
 27.     struct Iter_pair{ 
 28.         _InIt m_in; 
 29.         _OutIt m_out; 
 30.         Iter_pair(_InIt _in, _OutIt _out) 
 31.             :m_in(_in),m_out(_out){} 
 32.          
 33.         Iter_pair operator+(size_t off) const 
 34.         { 
 35.             return Iter_pair(m_in+off, m_out+off); 
 36.         } 
 37.         size_t operator-(Iter_pair rhs) const 
 38.         { 
 39.             return m_in-rhs.m_in; 
 40.         } 
 41.         bool operator<(Iter_pair rhs) const 
 42.         { 
 43.             return m_in<rhs.m_in; 
 44.         } 
 45.     }; 
 46.      
 47.     template<class _InIt, class _OutIt, class _Fn1> 
 48.     struct op_parallel_transform{ 
 49.         op_parallel_transform(_Fn1 _Func) 
 50.             :m_Func(_Func){} 
 51.         void operator()(const tbb::blocked_range<Iter_pair<_InIt,_OutIt> > &r) const 
 52.         { 
 53.             std::transform(r.begin().m_in, r.end().m_in, r.begin().m_out, m_Func); 
 54.         } 
 55.     private: 
 56.         _Fn1 m_Func; 
 57.     }; 
 58.     template<class _InIt, class _OutIt, class _Fn1> 
 59.     _OutIt _parallel_transform(_InIt _First, _InIt _Last, _OutIt _Dest, _Fn1 _Func, std::random_access_iterator_tag) 
 60.     { 
 61.          
 62.         typedef typename Iter_pair<_InIt,_OutIt> iter_pair_type; 
 63.         _OutIt LastDest = _Dest + (_Last - _First); 
 64.         iter_pair_type begin(_First, _Dest); 
 65.         iter_pair_type end(_Last, LastDest); 
 66.         tbb::blocked_range<iter_pair_type> x(begin, end); 
 67.         tbb::parallel_for(x, op_parallel_transform<_InIt,_OutIt,_Fn1>(_Func), tbb::auto_partitioner()); 
 68.         return LastDest; 
 69.     } 
 70.      
 71.     template<class _InIt> 
 72.     struct filter_in : tbb::filter{ 
 73.         filter_in(_InIt _First, _InIt _Last) 
 74.             :tbb::filter(true),m_First(_First), m_Last(_Last){} 
 75.         void* operator()(void*) 
 76.         { 
 77.             if(m_First==m_Last) return NULL; 
 78.             void* p = &(*m_First); 
 79.             ++m_First; 
 80.             return p; 
 81.         } 
 82.     private: 
 83.         _InIt m_First, m_Last; 
 84.     }; 
 85.     template<class _Fn1> 
 86.     struct filter_process : tbb::filter{ 
 87.         typedef typename _Fn1::result_type r_type; 
 88.         typedef typename _Fn1::argument_type a_type; 
 89.         filter_process(_Fn1 _Func) 
 90.             :tbb::filter(false),m_Func(_Func){} 
 91.         void* operator()(void* data) 
 92.         { 
 93.             a_type &at = *(a_type*)data; 
 94.             m_r = m_Func( at ); 
 95.             return &m_r; 
 96.         } 
 97.     private: 
 98.         _Fn1 m_Func; 
 99.         r_type m_r; 
 100. }; 
 101. template<class _OutIt, class _DataType> 
 102. struct filter_out : tbb::filter{ 
 103.     filter_out(_OutIt _Dest) 
 104.         :tbb::filter(true),m_Dest(_Dest){} 
 105.     void* operator()(void* data) 
 106.     { 
 107.         _DataType *p = (_DataType*) data; 
 108.         *m_Dest = *p; 
 109.         ++m_Dest; 
 110.         return NULL; 
 111.     } 
 112. private: 
 113.     _OutIt m_Dest; 
 114. }; 
 115. template<class _InIt, class _OutIt, class _Fn1> 
 116. _OutIt _parallel_transform(_InIt _First, _InIt _Last, _OutIt _Dest, _Fn1 _Func, std::forward_iterator_tag) 
 117. { 
 118.      
 119.     tbb::pipeline pipeline; 
 120.     filter_in<_InIt> f1(_First, _Last); 
 121.     filter_process<_Fn1> f2(_Func); 
 122.     filter_out<_OutIt, _Fn1::result_type> f3(_Dest); 
 123.     pipeline.add_filter(f1); 
 124.     pipeline.add_filter(f2); 
 125.     pipeline.add_filter(f3); 
 126.     pipeline.run(3); 
 127.     return _Dest; 
 128. } 
 129.  
 130. template<class _InIt, class _OutIt, class _Fn1> 
 131. inline 
 132. _OutIt parallel_transform(_InIt _First, _InIt _Last, _OutIt _Dest, _Fn1 _Func) 
 133. { 
 134.     typedef typename std::iterator_traits<_InIt>::iterator_category cat1; 
 135.     typedef typename std::iterator_traits<_OutIt>::iterator_category cat2; 
 136.     return _parallel_transform(_First, _Last, _Dest, _Func, both_random_helper<cat1,cat2>::Iter_cat()); 
 137. } 
 138.  
 139. struct SinFunctor 
 140.     :std::unary_function<double, double>{ 
 141.     double operator()(double &d) const 
 142.     { 
 143.          
 144.         double sum = 0; 
 145.         for(int i=0; i<10000; i++)  sum += sin(i*d); 
 146.         return sum; 
 147.     } 
 148. }; 
 149. int main() 
 150. { 
 151.      
 152.     std::vector<double> a(10000,1.5); 
 153.      
 154.     std::list<double>   b(10000,1.5); 
 155.     tbb::task_scheduler_init init; 
 156.     tbb::tick_count t0,t1; 
 157.     t0 = tbb::tick_count::now(); 
 158.     parallel_transform(a.begin(), a.end(), a.begin(), SinFunctor()); 
 159.     t1 = tbb::tick_count::now(); 
 160.     std::cout << "并行(随机迭代)" << (t1 - t0).seconds() << std::endl; 
 161.    
 162.     t0 = tbb::tick_count::now(); 
 163.     std::transform(a.begin(), a.end(), a.begin(), SinFunctor()); 
 164.     t1 = tbb::tick_count::now(); 
 165.     std::cout << "原版(随机迭代)" << (t1 - t0).seconds() << std::endl; 
 166.     t0 = tbb::tick_count::now(); 
 167.     parallel_transform(b.begin(), b.end(), b.begin(), SinFunctor()); 
 168.     t1 = tbb::tick_count::now(); 
 169.     std::cout << "并行(顺序迭代)" << (t1 - t0).seconds() << std::endl; 
 170.     t0 = tbb::tick_count::now(); 
 171.     std::transform(b.begin(), b.end(), b.begin(), SinFunctor()); 
 172.     t1 = tbb::tick_count::now(); 
 173.     std::cout << "原版(顺序迭代)"<< (t1 - t0).seconds() << std::endl; 
 174.    
 175.     std::cin.get(); 
 176.     return 0; 
 177. }