00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #ifndef COMPONENTS_TRIG_CPU_BARRIER_ACTION_H
00014 #define COMPONENTS_TRIG_CPU_BARRIER_ACTION_H
00015
00016 #include <vector>
00017 #include <cstdlib>
00018
00019 #include <sst/core/action.h>
00020 #include <sst/core/link.h>
00021 #include <sst/core/simulation.h>
00022 #include <sst/core/timeLord.h>
00023
00024 class barrier_action : public Action {
00025 public:
00026
00027 barrier_action() {
00028 setPriority(75);
00029
00030 min = 0xffffffff;
00031 max = 0;
00032 total_time = 0;
00033
00034 overall_min = 0xffffffff;
00035 overall_max = 0;
00036 overall_total_time = 0;
00037 overall_total_num = 0;
00038
00039 rand_init = false;
00040 max_init_rank = -1;
00041
00042 job_size = Simulation::getSimulation()->getNumRanks();
00043
00044
00045 Simulation::getSimulation()->insertActivity(Simulation::getSimulation()->getTimeLord()->getTimeConverter("1us")->getFactor(),this);
00046
00047
00048 }
00049
00050 void execute() {
00051
00052 Simulation *sim = Simulation::getSimulation();
00053
00054
00055
00056 boost::mpi::communicator world;
00057
00058
00059 int value = wake_up.size() - num_reporting;
00060 int out;
00061
00062 all_reduce( world, &value, 1, &out, std::plus<int>() );
00063
00064 if ( 0 == out ) {
00065
00066 SimTime_t total_num = wake_up.size();
00067 SimTime_t total_num_a;
00068 SimTime_t min_a;
00069 SimTime_t max_a;
00070 SimTime_t total_time_a;
00071 all_reduce( world, &total_num , 1, &total_num_a, std::plus<SimTime_t>() );
00072 all_reduce( world, &min, 1, &min_a, boost::mpi::minimum<SimTime_t>() );
00073 all_reduce( world, &max, 1, &max_a, boost::mpi::maximum<SimTime_t>() );
00074 all_reduce( world, &total_time, 1, &total_time_a, std::plus<SimTime_t>() );
00075
00076 if ( world.rank() == 0 ) {
00077 printf("Max time: %lu ns\n", (unsigned long) max_a);
00078 printf("Min time: %lu ns\n", (unsigned long) min_a);
00079 printf("Avg time: %lu ns\n", (unsigned long) (total_time_a/total_num_a));
00080 printf("Total num: %d\n", total_num_a);
00081 fflush(NULL);
00082 }
00083 resetBarrier();
00084 addTimeToOverallStats(max_a);
00085 resetStats();
00086 for ( int i = 0; i < wake_up.size(); i++ ) {
00087 wake_up[i]->Send(10,NULL);
00088 }
00089
00090 }
00091 SimTime_t next = sim->getCurrentSimCycle() +
00092 sim->getTimeLord()->getTimeConverter("1us")->getFactor();
00093 sim->insertActivity( next, this );
00094
00095 }
00096
00097 void
00098 barrier()
00099 {
00100 num_reporting++;
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113 }
00114
00115 void
00116 addTimeToStats(SimTime_t time)
00117 {
00118 if ( time < min ) min = time;
00119 if ( time > max ) max = time;
00120 total_time += time;
00121 }
00122
00123 void
00124 addTimeToOverallStats(SimTime_t time)
00125 {
00126 if ( time < overall_min ) overall_min = time;
00127 if ( time > overall_max ) overall_max = time;
00128 overall_total_time += time;
00129 overall_total_num++;
00130 }
00131
00132 void
00133 resetStats()
00134 {
00135 min = 0xffffffff;
00136 max = 0;
00137 total_time = 0;
00138 }
00139
00140 void
00141 printStats()
00142 {
00143 printf("Max time: %lu ns\n", (unsigned long) max);
00144 printf("Min time: %lu ns\n", (unsigned long) min);
00145 printf("Avg time: %lu ns\n", (unsigned long) (total_time/wake_up.size()));
00146 printf("Total num: %d\n", wake_up.size());
00147 fflush(NULL);
00148 }
00149
00150 void
00151 printOverallStats()
00152 {
00153 printf("Overall Max time: %lu ns\n", (unsigned long) overall_max);
00154 printf("Overall Min time: %lu ns\n", (unsigned long) overall_min);
00155 printf("Overall Avg time: %lu ns\n", (unsigned long) (overall_total_time/overall_total_num));
00156 printf("Overall Total num: %d\n", overall_total_num);
00157 fflush(NULL);
00158 }
00159
00160 int
00161 getRand(int rank, int max)
00162 {
00163 if (!rand_init) {
00164 srand(1);
00165 rand_init = true;
00166 }
00167 if ( max == 0 ) return 0;
00168 if ( max_init_rank < rank ) {
00169 for ( int i = max_init_rank + 1; i <= rank; i++ ) {
00170 rand_nums.push_back(rand());
00171 }
00172
00173 }
00174
00175 return rand_nums[rank] % max;
00176 }
00177
00178 void
00179 addWakeUp(Link* link)
00180 {
00181 wake_up.push_back(link);
00182 }
00183
00184
00185
00186
00187
00188
00189
00190
00191 void
00192 resetBarrier()
00193 {
00194 num_reporting = 0;
00195 }
00196
00197
00198 private:
00199 SimTime_t min;
00200 SimTime_t max;
00201 SimTime_t total_time;
00202 int num_reporting;
00203
00204 SimTime_t overall_min;
00205 SimTime_t overall_max;
00206 SimTime_t overall_total_time;
00207 int overall_total_num;
00208
00209 bool rand_init;
00210 int max_init_rank;
00211 std::vector<int> rand_nums;
00212
00213 std::vector<Link*> wake_up;
00214
00215 int job_size;
00216
00217
00218 };
00219
00220 #endif // COMPONENTS_TRIG_CPU_BARRIER_ACTION_H