1 #include <chrono>
2 #include <string>
3 #include <cstring>
4 
5 #ifndef UNIVERSE_H_
6 #define UNIVERSE_H_
7 
8 inline const int UNIVERSE_WIDTH {1024};
9 inline const int UNIVERSE_HEIGHT {512};
10 
11 #include "video.h"
12 
13 class Universe {
14 public:
15     enum {
16         UniverseWidth  = UNIVERSE_WIDTH,
17         UniverseHeight = UNIVERSE_HEIGHT
18     };
19 private:
20     //in order to avoid performance degradation due to cache aliasing issue
21     //some padding is needed after each row in array, and between array themselves.
22     //the padding is achieved by adjusting number of rows and columns.
23     //as the compiler is forced to place class members of the same clause in order of the
24     //declaration this seems to be the right way of padding.
25 
26     //magic constants added below are chosen experimentally for 1024x512.
27     enum {
28         MaxWidth = UniverseWidth+1,
29         MaxHeight = UniverseHeight+3
30     };
31 
32     typedef float ValueType;
33 
34     //! Horizontal stress
35     ValueType S[MaxHeight][MaxWidth];
36 
37     //! Velocity at each grid point
38     ValueType V[MaxHeight][MaxWidth];
39 
40     //! Vertical stress
41     ValueType T[MaxHeight][MaxWidth];
42 
43     //! Coefficient related to modulus
44     ValueType M[MaxHeight][MaxWidth];
45 
46     //! Damping coefficients
47     ValueType D[MaxHeight][MaxWidth];
48 
49     //! Coefficient related to lightness
50     ValueType L[MaxHeight][MaxWidth];
51 
52     enum { ColorMapSize = 1024};
53     color_t ColorMap[4][ColorMapSize];
54 
55     enum MaterialType {
56         WATER=0,
57         SANDSTONE=1,
58         SHALE=2
59     };
60 
61     //! Values are MaterialType, cast to an unsigned char to save space.
62     unsigned char material[MaxHeight][MaxWidth];
63 
64 private:
65     enum { DamperSize = 32};
66 
67     int pulseTime;
68     int pulseCounter;
69     int pulseX;
70     int pulseY;
71 
72     drawing_memory drawingMemory;
73 
74     std::string _model {"tf"};
75 
76 public:
get_model()77     const std::string& get_model() { return _model; }
set_model(std::string m)78     void set_model(std::string m) { _model = m; }
79     void InitializeUniverse(video const& colorizer);
80 
81     bool TryPutNewPulseSource(int x, int y);
82     void SetDrawingMemory(const drawing_memory &dmem);
83 
84     struct Rectangle {
85       struct std::pair<int,int> xRange;
86       struct std::pair<int,int> yRange;
87       Rectangle (int startX, int startY, int width, int height):xRange(startX,width),yRange(startY,height){}
88       int StartX() const {return xRange.first;}
89       int StartY() const {return yRange.first;}
90       int Width()   const {return xRange.second;}
91       int Height()  const {return yRange.second;}
92       int EndX() const {return xRange.first + xRange.second;}
93       int EndY() const {return yRange.first + yRange.second;}
94     };
95 
96     void UpdatePulse();
97     void UpdateStress(Rectangle const& r);
98     void UpdateVelocity(Rectangle const& r);
99 
100     friend struct UpdateStressBody;
101     friend struct UpdateVelocityBody;
102 
103     //void ParallelUpdateUniverse();
104     //void ParallelUpdateStress(tbb::affinity_partitioner &affinity);
105     //void ParallelUpdateVelocity(tbb::affinity_partitioner &affinity);
106 
107     void SerialUpdateVelocity();
108     void SerialUpdateUniverse();
109     void SerialUpdateStress();
110 };
111 
112 std::chrono::microseconds measure_time_tbb(unsigned, unsigned, Universe &);
113 std::chrono::microseconds measure_time_taskflow(unsigned, unsigned, Universe &);
114 
115 
116 #endif /* UNIVERSE_H_ */
117