Browse Source

hypervisor: correct computation of idle

Andra Hugo 11 years ago
parent
commit
2769aaa8cb

+ 5 - 0
sc_hypervisor/include/sc_hypervisor_monitoring.h

@@ -127,6 +127,11 @@ struct sc_hypervisor_wrapper
 	/* boolean indicating if we add the idle of this worker to 
 	   the idle of the context */
 	unsigned compute_idle[STARPU_NMAXWORKERS];
+
+	/* boolean indicating if we add the entiere idle of this 
+	   worker to the idle of the context or just half*/
+	unsigned compute_partial_idle[STARPU_NMAXWORKERS];
+
 };
 
 /* return the wrapper of context that saves its monitoring information */

+ 1 - 6
sc_hypervisor/src/policies_utils/policy_tools.c

@@ -465,12 +465,7 @@ unsigned sc_hypervisor_check_idle(unsigned sched_ctx, int worker)
 	struct sc_hypervisor_policy_config *config = sc_w->config;
 	if(config != NULL)
 	{
-		double end_time = starpu_timing_now();
-		double idle = (end_time - sc_w->idle_start_time[worker]) / 1000000.0; /* in seconds */ 
-		double idle_time = sc_w->idle_time[worker] + idle;
-
-
-		if(idle_time > config->max_idle[worker])
+		if(sc_w->idle_time[worker] > config->max_idle[worker])
 		{
 //			printf("w%d/ctx%d: current idle %lf all idle %lf max_idle %lf\n", worker, sched_ctx, idle, idle_time, config->max_idle[worker]);
 			return 1;

+ 50 - 28
sc_hypervisor/src/sc_hypervisor.c

@@ -209,6 +209,7 @@ void* sc_hypervisor_init(struct sc_hypervisor_policy *hypervisor_policy)
 			hypervisor.sched_ctx_w[i].total_elapsed_flops[j] = 0.0;
 			hypervisor.sched_ctx_w[i].worker_to_be_removed[j] = 0;
 			hypervisor.sched_ctx_w[i].compute_idle[j] = 1;
+			hypervisor.sched_ctx_w[i].compute_partial_idle[j] = 0;
 		}
 	}
 
@@ -313,7 +314,6 @@ void sc_hypervisor_register_ctx(unsigned sched_ctx, double total_flops)
 	hypervisor.sched_ctx_w[sched_ctx].total_flops = total_flops;
 	hypervisor.sched_ctx_w[sched_ctx].remaining_flops = total_flops;
 	hypervisor.resize[sched_ctx] = 1;
-	hypervisor.sched_ctx_w[sched_ctx].hyp_react_start_time = starpu_timing_now();
 	starpu_pthread_mutex_unlock(&act_hypervisor_mutex);
 }
 
@@ -831,7 +831,7 @@ void sc_hypervisor_update_resize_interval(unsigned *sched_ctxs, int nsched_ctxs)
 					elapsed_time_worker[worker] = 0.0;
 				else
 					elapsed_time_worker[worker] = (end_time - hypervisor.sched_ctx_w[sched_ctx].start_time_w[worker]) / 1000000.0;
-				
+
 				if(hypervisor.sched_ctx_w[sched_ctx].idle_start_time[worker] == 0.0)
 				{
 					idle_time = hypervisor.sched_ctx_w[sched_ctx].idle_time[worker]; /* in seconds */
@@ -948,31 +948,35 @@ static void notify_pushed_task(unsigned sched_ctx, int worker)
 /* notifies the hypervisor that the worker spent another cycle in idle time */
 static void notify_idle_cycle(unsigned sched_ctx, int worker, double idle_time)
 {
-	if(hypervisor.resize[sched_ctx])
+	struct sc_hypervisor_wrapper *sc_w = &hypervisor.sched_ctx_w[sched_ctx];
+	sc_w->current_idle_time[worker] += idle_time;
+	
+	if(sc_w->idle_start_time[worker] == 0.0 && sc_w->hyp_react_start_time != 0.0)
+		sc_w->idle_start_time[worker] = starpu_timing_now();
+	
+
+	if(sc_w->idle_start_time[worker] > 0.0)
 	{
-		struct sc_hypervisor_wrapper *sc_w = &hypervisor.sched_ctx_w[sched_ctx];
-		sc_w->current_idle_time[worker] += idle_time;
+		double end_time  = starpu_timing_now();
+		sc_w->idle_time[worker] += (end_time - sc_w->idle_start_time[worker]) / 1000000.0; /* in seconds */
+	}
+	
+	hypervisor.sched_ctx_w[sched_ctx].idle_start_time[worker] = starpu_timing_now();
 
-		if(sc_w->idle_start_time[worker] == 0.0)
-			sc_w->idle_start_time[worker] = starpu_timing_now();
-		
-		if(hypervisor.policy.handle_idle_cycle)
+	if(hypervisor.resize[sched_ctx] && hypervisor.policy.handle_idle_cycle)
+	{
+		if(sc_w->sched_ctx != STARPU_NMAX_SCHED_CTXS && sc_w->hyp_react_start_time != 0.0)
 		{
-			double curr_time = starpu_timing_now();
-			double elapsed_time = (curr_time - sc_w->hyp_react_start_time) / 1000000.0; /* in seconds */
-			if(sc_w->sched_ctx != STARPU_NMAX_SCHED_CTXS && elapsed_time > sc_w->config->max_idle[worker])
+			if(sc_hypervisor_check_idle(sched_ctx, worker))
 			{
-				if(sc_hypervisor_check_idle(sched_ctx, worker))
-				{
-					hypervisor.policy.handle_idle_cycle(sched_ctx, worker);
-				}
-				sc_w->hyp_react_start_time = starpu_timing_now();
+				hypervisor.policy.handle_idle_cycle(sched_ctx, worker);
 			}
 		}
 	}
 	return;
 }
 
+
 /* notifies the hypervisor that the worker is no longer idle and a new task was pushed on its queue */
 static void notify_poped_task(unsigned sched_ctx, int worker)
 {
@@ -981,18 +985,33 @@ static void notify_poped_task(unsigned sched_ctx, int worker)
 
 	hypervisor.sched_ctx_w[sched_ctx].exec_start_time[worker] = starpu_timing_now();
 
-	if(hypervisor.resize[sched_ctx])
-		hypervisor.sched_ctx_w[sched_ctx].current_idle_time[worker] = 0.0;
-
-	struct sc_hypervisor_wrapper *sc_w = &hypervisor.sched_ctx_w[sched_ctx];
-
-	if(sc_w->idle_start_time[worker] > 0.0)
+	if(hypervisor.sched_ctx_w[sched_ctx].idle_start_time[worker] > 0.0)
 	{
+		int ns = hypervisor.nsched_ctxs;
+		int j;
+		for(j = 0; j < ns; j++)
+		{
+			if(hypervisor.sched_ctxs[j] != sched_ctx)
+			{
+				if(hypervisor.sched_ctx_w[hypervisor.sched_ctxs[j]].idle_start_time[worker] > 0.0)
+					hypervisor.sched_ctx_w[hypervisor.sched_ctxs[j]].compute_partial_idle[worker] = 1;
+			}
+		}
 		double end_time  = starpu_timing_now();
-		sc_w->idle_time[worker] += (end_time - sc_w->idle_start_time[worker]) / 1000000.0; /* in seconds */
-		sc_w->idle_start_time[worker] = 0.0;
-	}
+		double idle = (end_time - hypervisor.sched_ctx_w[sched_ctx].idle_start_time[worker]) / 1000000.0; /* in seconds */
 			
+		if(hypervisor.sched_ctx_w[sched_ctx].compute_partial_idle[worker])
+			hypervisor.sched_ctx_w[sched_ctx].idle_time[worker] += idle / 2.0;
+		else
+			hypervisor.sched_ctx_w[sched_ctx].idle_time[worker] += idle;
+
+		hypervisor.sched_ctx_w[sched_ctx].compute_partial_idle[worker] = 0;
+		hypervisor.sched_ctx_w[sched_ctx].idle_start_time[worker] = 0.0;
+	}
+
+	if(hypervisor.resize[sched_ctx])
+		hypervisor.sched_ctx_w[sched_ctx].current_idle_time[worker] = 0.0;
+				
 	if(hypervisor.policy.handle_idle_end)
 		hypervisor.policy.handle_idle_end(sched_ctx, worker);
 
@@ -1029,13 +1048,16 @@ static void notify_post_exec_task(struct starpu_task *task, size_t data_size, ui
 	if(hypervisor.resize[sched_ctx])
 	{	
 		if(hypervisor.policy.handle_poped_task)
-		{
+		{	
+			if(hypervisor.sched_ctx_w[sched_ctx].hyp_react_start_time == 0.0)
+				hypervisor.sched_ctx_w[sched_ctx].hyp_react_start_time = starpu_timing_now();
+
 			double curr_time = starpu_timing_now();
 			double elapsed_time = (curr_time - hypervisor.sched_ctx_w[sched_ctx].hyp_react_start_time) / 1000000.0; /* in seconds */
 			if(hypervisor.sched_ctx_w[sched_ctx].sched_ctx != STARPU_NMAX_SCHED_CTXS && elapsed_time > hypervisor.sched_ctx_w[sched_ctx].config->time_sample)
 			{
-				hypervisor.sched_ctx_w[sched_ctx].hyp_react_start_time = starpu_timing_now();
 				hypervisor.policy.handle_poped_task(sched_ctx, worker, task, footprint);
+				hypervisor.sched_ctx_w[sched_ctx].hyp_react_start_time = starpu_timing_now();
 			}
 		}
 	}