00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include <vector>
00019
00020 #include "app.h"
00021 #include "time_stats.h"
00022 #include "client_types.h"
00023 #include "../sched/edf_sim.h"
00024
00025 using std::vector;
00026
00027 #define WORK_FETCH_DONT_NEED 0
00028
00029
00030 #define WORK_FETCH_OK 1
00031
00032
00033 #define WORK_FETCH_NEED 2
00034
00035
00036 #define WORK_FETCH_NEED_IMMEDIATELY 3
00037
00038
00039
00040 struct SIM_RESULTS {
00041 double cpu_used;
00042 double cpu_wasted;
00043 double cpu_idle;
00044 int nresults_met_deadline;
00045 int nresults_missed_deadline;
00046 double share_violation;
00047 double monotony;
00048 double cpu_wasted_frac;
00049 double cpu_idle_frac;
00050
00051 void compute();
00052 void print(FILE* f, const char* title=0);
00053 void parse(FILE* f);
00054 void add(SIM_RESULTS& r);
00055 void divide(int);
00056 void clear();
00057 };
00058
00059 struct PROJECT_RESULTS {
00060 double cpu_used;
00061 double cpu_wasted;
00062 int nresults_met_deadline;
00063 int nresults_missed_deadline;
00064 };
00065
00066 class NORMAL_DIST {
00067 public:
00068 double mean;
00069 double stdev;
00070 int parse(XML_PARSER&, char* end_tag);
00071 double sample();
00072 };
00073
00074 class UNIFORM_DIST {
00075 public:
00076 double lo;
00077 double hi;
00078 int parse(XML_PARSER&, char* end_tag);
00079 double sample();
00080 };
00081
00082 class RANDOM_PROCESS {
00083 double last_time;
00084 double time_left;
00085 bool value;
00086 double off_lambda;
00087 public:
00088 double frac;
00089 double lambda;
00090 int parse(XML_PARSER&, char* end_tag);
00091 bool sample(double);
00092 void init();
00093 RANDOM_PROCESS();
00094 };
00095
00096 class SIM_APP: public APP {
00097 public:
00098 double latency_bound;
00099 double fpops_est;
00100 NORMAL_DIST fpops;
00101 NORMAL_DIST checkpoint_period;
00102 double working_set;
00103 double weight;
00104
00105 SIM_APP(){}
00106 int parse(XML_PARSER&);
00107 };
00108
00109 class SIM_PROJECT: public PROJECT {
00110 public:
00111 RANDOM_PROCESS available;
00112 int index;
00113 int result_index;
00114 double idle_time;
00115 double idle_time_sumsq;
00116 bool idle;
00117 int max_infeasible_count;
00118
00119 int completed_task_count;
00120 double completions_ratio_mean;
00121 double completions_ratio_s;
00122 double completions_ratio_stdev;
00123 double completions_required_stdevs;
00124
00125 int parse(XML_PARSER&);
00126 PROJECT_RESULTS project_results;
00127 void print_results(FILE*, SIM_RESULTS&);
00128 void init();
00129 void backoff();
00130 void update_dcf_stats(RESULT*);
00131 };
00132
00133 class SIM_HOST: public HOST_INFO {
00134 public:
00135 RANDOM_PROCESS available;
00136 RANDOM_PROCESS idle;
00137 double connection_interval;
00138
00139 int parse(XML_PARSER&);
00140 };
00141
00142 class CLIENT_STATE {
00143 public:
00144 double now;
00145 vector<PROJECT*> projects;
00146 vector<WORKUNIT*> workunits;
00147 vector<RESULT*> results;
00148 vector<APP*> apps;
00149 ACTIVE_TASK_SET active_tasks;
00150 GLOBAL_PREFS global_prefs;
00151 SIM_HOST host_info;
00152 TIME_STATS time_stats;
00153 COPROCS coprocs;
00154 CLIENT_STATE();
00155 bool initialized;
00156 bool run_cpu_benchmarks;
00157 FILE* html_out;
00158 void html_start(bool);
00159 void html_rec();
00160 void html_end(bool);
00161 std::string html_msg;
00162 double share_violation();
00163 double monotony();
00164
00165 private:
00166 double app_started;
00167 public:
00168 ACTIVE_TASK* lookup_active_task_by_result(RESULT*);
00169 int report_result_error(RESULT&, const char *format, ...);
00170 double available_ram();
00171 double max_available_ram();
00172 void set_client_state_dirty(const char*);
00173 RESULT* lookup_result(PROJECT*, const char*);
00174
00175
00176 private:
00177 double debt_interval_start;
00178 double total_wall_cpu_time_this_debt_interval;
00179
00180 double fetchable_resource_share();
00181 double total_cpu_time_this_debt_interval;
00182 double cpu_shortfall;
00183 bool work_fetch_no_new_work;
00184 bool must_enforce_cpu_schedule;
00185 bool must_schedule_cpus;
00186 bool must_check_work_fetch;
00187 std::vector <RESULT*> ordered_scheduled_results;
00188 void assign_results_to_projects();
00189 RESULT* largest_debt_project_best_result();
00190 RESULT* earliest_deadline_result();
00191 void reset_debt_accounting();
00192 void adjust_debts();
00193 bool possibly_schedule_cpus();
00194 void schedule_cpus();
00195 bool enforce_schedule();
00196 bool no_work_for_a_cpu();
00197 void rr_simulation();
00198 void make_running_task_heap(vector<ACTIVE_TASK*>&, double&);
00199 void print_deadline_misses();
00200 public:
00201 double retry_shmem_time;
00202 inline double work_buf_min() {
00203 return global_prefs.work_buf_min_days * 86400;
00204 }
00205 double work_buf_additional() {
00206 return global_prefs.work_buf_additional_days * 86400;
00207 }
00208 inline double work_buf_total() {
00209 double x = work_buf_min() + work_buf_additional();
00210 if (x < 1) x = 1;
00211 return x;
00212 }
00213
00214 void request_enforce_schedule(const char*);
00215 void request_schedule_cpus(const char*);
00216 bool sufficient_coprocs(APP_VERSION&);
00217 void reserve_coprocs(APP_VERSION&);
00218 void free_coprocs(APP_VERSION&);
00219
00220
00221 private:
00222 double total_resource_share();
00223 double potentially_runnable_resource_share();
00224 double nearly_runnable_resource_share();
00225 public:
00226 double runnable_resource_share();
00227 void request_work_fetch(const char*);
00228
00229
00230
00231
00232
00233
00234
00235 int quit_activities();
00236 void set_ncpus();
00237 double estimate_cpu_time(WORKUNIT&);
00238 double get_fraction_done(RESULT* result);
00239 int input_files_available(RESULT*, bool, FILE_INFO** f=0);
00240 int ncpus;
00241
00242 private:
00243 int nslots;
00244
00245 int app_finished(ACTIVE_TASK&);
00246 bool start_apps();
00247 bool handle_finished_apps();
00248 public:
00249 ACTIVE_TASK* get_task(RESULT*);
00250
00251
00252 private:
00253 bool contacted_sched_server;
00254 int overall_work_fetch_urgency;
00255 double avg_proc_rate();
00256
00257
00258 public:
00259 int proj_min_results(PROJECT*, double);
00260 void check_project_timeout();
00261 PROJECT* next_project_master_pending();
00262 PROJECT* next_project_sched_rpc_pending();
00263 PROJECT* next_project_trickle_up_pending();
00264 PROJECT* next_project_need_work();
00265 PROJECT* find_project_with_overdue_results();
00266 double overall_cpu_frac();
00267 double time_until_work_done(PROJECT*, int, double);
00268 bool compute_work_requests();
00269 void scale_duration_correction_factors(double);
00270 void generate_new_host_cpid();
00271 void compute_nuploading_results();
00272
00274 void make_job(SIM_PROJECT*, WORKUNIT*, RESULT*);
00275 void handle_completed_results();
00276 void get_workload(vector<IP_RESULT>&);
00277 int parse_projects(char*);
00278 int parse_host(char*);
00279 void simulate();
00280 bool scheduler_rpc_poll();
00281 bool simulate_rpc(PROJECT*);
00282 void print_project_results(FILE*);
00283 };
00284
00285 class NET_STATUS {
00286 public:
00287 bool have_sporadic_connection;
00288 };
00289
00290 extern CLIENT_STATE gstate;
00291 extern NET_STATUS net_status;
00292 extern FILE* logfile;
00293 extern bool user_active;
00294 extern SIM_RESULTS sim_results;
00295 extern double calculate_exponential_backoff(
00296 int n, double MIN, double MAX
00297 );
00298
00299 extern bool dcf_dont_use;
00300 extern bool dcf_stats;
00301 extern bool cpu_sched_rr_only;
00302 extern bool dual_dcf;
00303 extern bool work_fetch_old;