140 likes | 283 Views
Tips for Programming Assignment #1. Requirements. Measure success ratio, deadline miss ratio & QoS level for different loads = 0.4, 0.6, 0.8, ..., 1.8, 2.0 for three different approaches Simple EDF & RMS without admission control or QoS degradation EDF & RMS + admission control
E N D
Tips for Programming Assignment #1 Introduction to Real-Time Embedded Systems
Requirements • Measure success ratio, deadline miss ratio & QoS level for different loads = 0.4, 0.6, 0.8, ..., 1.8, 2.0 for three different approaches • Simple EDF & RMS without admission control or QoS degradation • EDF & RMS + admission control • EDF & RMS + admission control + QoS degradation (e.g., imprecise computation) • Run 10 simulations using different seed numbers for each load and take the average success ratio, miss ratio & QoS level for every approach described above Introduction to Real-Time Embedded Systems
Time-Driven vs. Event-Driven Simulation • Time-Driven • for (usnigned int t=1; t=600000; t++) { Do something at time t; t++; } • Easy but slow Introduction to Real-Time Embedded Systems
Time-Driven vs. Event-Driven Simulation • Event-Driven • Fast • Process the current event • Skip to the next event • Most professional simulators are event-driven • More difficult • Should be careful to properly manage the event queue • For this assignment, you can do time-driven simulation Introduction to Real-Time Embedded Systems
Overall structure int main(char *argv, int argc) { if (argc < NUM_ARGS) cout << “error”; exit(-1); /* argv[0] -> EDF or RMS */ /* argv[1] -> estErr (execution time estimation error); removed from PA #1 */ /* argv[2] -> turn on/off QoS degradation */ /* argv[3] -> load */ for (unsigned int i=0; i<NUM_SIMULATIONS; i++) { for (unsigned int t=0; t<MAX_TIME; t++) /* one simulation run */ { /* Use a different seed number for each simulation run */ bool generated = generate_task(t,load); if (generated) admission_control(num_tasks); generate_jobs(t); schedule(); dispatch(); step_run(); collect_statistics(); /* #submitted, #admitted, #timely, QoS */ } cout << “Scheduling algorithm = ” << /* print EDF or RMS according to argv[0] */ << endl; cout << “estErr = “ << argv[1] << endl; cout << “QoS = “ << /* average QoS in [0,1] */ << endl; cout << “Load = “ << argv[3] << endl; cout << “deadline miss ratio = “ << 1 - (#timely / #submitted) << endl; clean_up(); } Introduction to Real-Time Embedded Systems
Skeletion of class source() #define MIN_EXEC_TIME 5 //5ms #define MAX_EXEC_TIME 20 //20ms #define MIN_PERIOD 20 #define MAX_PERIOD 500 #define MAX_SOURCES class task() { int task_id; bool admitted; //admitted or not int next_job_arrival_time; int exec_time; int period; //relative deadline = period float u; //utilization int qos; //1 = high, 0.5 = low } task *s[MAX_SOURCES]; #define AVERAGE_TASK_INTER_ARRIVAL_TIME int num_tasks = 0; //Use newranrandom number generator to create Poisson & uniform distributions Poisson P(AVERAGE_TASK_INTER_ARRIVAL_TIME); Uniform Unif(); Introduction to Real-Time Embedded Systems
generate_task(t, load): Generate a priodic task // main u_total = 0.0; //total utilization next_task_arrival_time = t + (int) P.Next(); for (unsigned int t=0; t<MAX_TIME; t++) /* one simulation run */ { if (t == next_task_arrival_time) { generate_task(t, load); next_task_arrival_time = t + (int) P.Next(); } ....... } Introduction to Real-Time Embedded Systems
void generate_task(t, load) { s[num_tasks] = new task(); s[num_tasks]->exec_time = (unsigned int) (MIN_EXEC_TIME + Unif.Next() * (MAX_EXEC_TIME – MIN_EXEC_TIME)); s[num_tasks]->period = (unsigned int) (MIN_PERIOD + Unif.Next()*(MAX_PERIOD – MIN_PERIOD)) s[num_tasks]->u = s[num_tasks]->exec_time / s[num_tasks]->period; if (u_total + s[num_tasks]->u > load) //Delete this task and return false else { s[num_tasks]-> next_job_arrival_time = t; num_tasks++; } } Introduction to Real-Time Embedded Systems
generate_jobs(t) void generate_jobs(t) { for (int i=0; i<=num_tasks; i++) { if (s[i]->admitted && s[i]-> next_job_arrival_time == t) { // Generate a job with s[i]->period, // s[i]->exec_time, etc. and insert it // into the ready queue s[i]-> next_job_arrival_time = t + s[i]->period; } } } Introduction to Real-Time Embedded Systems
admission_control() void admission_control(unsigned int task_id) { if (u_total + s[task_id] <= U_BOUND) admit(task_id); else degrade_qos(task_id); } Introduction to Real-Time Embedded Systems
admit(tid) & degrade(tid) // Note: tid indicates task_id void admit(unsigned int tid) { s[tid]->admitted = true; } void degrade_qos(unsigned int tid) { if (u_total + 0.5 * s[sid]->u <= U_BOUND) //imprecise computation { s[tid]->qos = LOW; s[tid]->exec_time = 0.5 * s[tid]->exec_time; s[tid]->u = 0.5 * s[tid]->u; admit(tid); return; } else { /* Degrade the QoS of the tasks already in the system to admit the new task sid */ /* Stop degradation, admit task sid, and return if the new U_total <= U_BOUND */ } s[tid]->admitted = false; /* Reject task tid; you cannot admit it even after degrading all the tasks in the system */ } Introduction to Real-Time Embedded Systems
schedule() void schedule() { // sort the ready queue according to // the selected scheduling algorithm, i.e., // EDF or RM } Introduction to Real-Time Embedded Systems
dispatch() & step_run() job *dispatch() { /* return the highest priority job amog the currently running task and the tasks in the ready queue */ } step_run(unsigned int t, job *highest) { highest->exec_time--; if (highest->exec_time == 0) if (its deadline <= t) #timely++; /* continue to run a job even if its deadline is missed */ } Introduction to Real-Time Embedded Systems
Expected Outcome • Show the following: • No deadline miss for admitted tasks if admission control is applied • Improved success ratio and degraded QoS after applying admission control/imprecise computation Introduction to Real-Time Embedded Systems