1 #include "universe.h"
2 #include <tbb/task_scheduler_init.h>
3 #include <tbb/flow_graph.h>
4 #include <tbb/partitioner.h>
5 #include <tbb/blocked_range.h>
6 #include <tbb/parallel_for.h>
7 
8 
9 struct UpdateStressBody {
10   Universe & u_;
UpdateStressBodyUpdateStressBody11   UpdateStressBody(Universe & u):u_(u){}
operator ()UpdateStressBody12   void operator()( const tbb::blocked_range<int>& range ) const {
13     u_.UpdateStress(Universe::Rectangle(0, range.begin(), u_.UniverseWidth-1, range.size()));
14   }
15 };
16 
17 struct UpdateVelocityBody {
18   Universe & u_;
UpdateVelocityBodyUpdateVelocityBody19   UpdateVelocityBody(Universe & u):u_(u){}
operator ()UpdateVelocityBody20   void operator()( const tbb::blocked_range<int>& y_range ) const {
21     u_.UpdateVelocity(Universe::Rectangle(1, y_range.begin(), u_.UniverseWidth-1, y_range.size()));
22   }
23 };
24 
25 
26 // the wavefront computation
seismic_tbb(unsigned num_threads,unsigned num_frames,Universe & u)27 void seismic_tbb(unsigned num_threads, unsigned num_frames, Universe& u) {
28 
29   using namespace tbb;
30   using namespace tbb::flow;
31 
32   tbb::task_scheduler_init init(num_threads);
33 
34   static tbb::affinity_partitioner affinity;
35 
36   for(unsigned i=0u; i<num_frames; ++i ) {
37     u.UpdatePulse();
38     tbb::parallel_for(tbb::blocked_range<int>( 0, u.UniverseHeight-1 ), // Index space for loop
39                       UpdateStressBody(u),                            // Body of loop
40                       affinity);                                      // Affinity hint
41     tbb::parallel_for(tbb::blocked_range<int>( 1, u.UniverseHeight ), // Index space for loop
42                       UpdateVelocityBody(u),                        // Body of loop
43                       affinity);                                    // Affinity hint
44   }
45 }
46 
measure_time_tbb(unsigned num_threads,unsigned num_frames,Universe & u)47 std::chrono::microseconds measure_time_tbb(unsigned num_threads, unsigned num_frames, Universe& u) {
48   auto beg = std::chrono::high_resolution_clock::now();
49   seismic_tbb(num_threads, num_frames, u);
50   auto end = std::chrono::high_resolution_clock::now();
51   return std::chrono::duration_cast<std::chrono::microseconds>(end - beg);
52 }
53 
54 
55