1.#include
2.#include
3.#include
4.#include
5.#include
6.#include
7.#include
8.#include
9.#include
10.#include
11.//-----------------随机存取迭代器版本-------------------------------------
12.//both_random_helper,作用:测试两个模板是否都是random_access_iterator_tag
13.//是则Iter_cat返回random_access_iterator_tag
14.//否则返回forward_iterator_tag
15.template
16.structboth_random_helper{
17.typedefstd::forward_iterator_tag Iter_cat;
18.};
19.template<>
20.structboth_random_helper<
21.std::random_access_iterator_tag,
22.std::random_access_iterator_tag>{
23.typedefstd::random_access_iterator_tag Iter_cat;
24.};
25.//用于存放一对迭代器
26.template
27.structIter_pair{
28._InIt m_in;
29._OutIt m_out;
30.Iter_pair(_InIt _in, _OutIt _out)
31.:m_in(_in),m_out(_out){}
32.//支持blocked_range拆分
33.Iter_pair operator+(size_toff)const
34.{
35.returnIter_pair(m_in+off, m_out+off);
36.}
37.size_toperator-(Iter_pair rhs)const
38.{
39.returnm_in-rhs.m_in;
40.}
41.booloperator
42.{
43.returnm_in
44.}
45.};
46.//随机存取迭代器版本
47.template
48.structop_parallel_transform{
49.op_parallel_transform(_Fn1 _Func)
50.:m_Func(_Func){}
51.voidoperator()(consttbb::blocked_range > &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
59._OutIt _parallel_transform(_InIt _First, _InIt _Last, _OutIt _Dest, _Fn1 _Func, std::random_access_iterator_tag)
60.{
61.//使用parallel_for来处理
62.typedeftypenameIter_pair<_init> 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 x(begin, end);
67.tbb::parallel_for(x, op_parallel_transform<_init>(_Func), tbb::auto_partitioner());
68.returnLastDest;
69.}
70.//-----------------顺序存取迭代器版本-------------------------------------
71.template
72.structfilter_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)returnNULL;
78.void* p = &(*m_First);
79.++m_First;
80.returnp;
81.}
82.private:
83._InIt m_First, m_Last;
84.};
85.template
86.structfilter_process : tbb::filter{
87.typedeftypename_Fn1::result_type r_type;
88.typedeftypename_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
102.structfilter_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.returnNULL;
111.}
112.private:
113._OutIt m_Dest;
114.};
115.template
116._OutIt _parallel_transform(_InIt _First, _InIt _Last, _OutIt _Dest, _Fn1 _Func, std::forward_iterator_tag)
117.{
118.//使用管线pipeline来处理
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.//----------------------parallel_transform----------------------------
130.template
131.inline
132._OutIt parallel_transform(_InIt _First, _InIt _Last, _OutIt _Dest, _Fn1 _Func)
133.{
134.typedeftypenamestd::iterator_traits<_init>::iterator_category cat1;
135.typedeftypenamestd::iterator_traits<_outit>::iterator_category cat2;
136.return_parallel_transform(_First, _Last, _Dest, _Func, both_random_helper::Iter_cat());
137.}
138.//测试代码
139.structSinFunctor
140.:std::unary_function{
141.doubleoperator()(double&d)const
142.{
143.//高强度运算
144.doublesum = 0;
145.for(inti=0; i<10000; i++) sum += sin(i*d);
146.returnsum;
147.}
148.};
149.intmain()
150.{
151.//随机存取迭代
152.std::vector a(10000,1.5);
153.//顺序存取迭代
154.std::list 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 <
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 <
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 <
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 <
174.
175.std::cin.get();
176.return0;
177.}