Browse Source

Separate out STATUS_SLEEPING_SCHEDULING state from STATUS_SLEEPING state

When running the scheduler while being idle, workers do not go in the
STATUS_SCHEDULING state, so that that time is considered as idle time
instead of overhead.

We however want starpu_wake_worker_relax_light to use the fast path also in
that case.
Samuel Thibault 5 years ago
parent
commit
c3d8461d25

+ 4 - 2
src/core/errorcheck.h

@@ -1,6 +1,6 @@
 /* StarPU --- Runtime system for heterogeneous multicore architectures.
  *
- * Copyright (C) 2009-2011,2013,2014,2017                 Université de Bordeaux
+ * Copyright (C) 2009-2011,2013,2014,2017,2019            Université de Bordeaux
  * Copyright (C) 2010,2011,2015,2017                      CNRS
  * Copyright (C) 2017                                     Inria
  *
@@ -39,7 +39,9 @@ enum _starpu_worker_status
 	STATUS_SCHEDULING,
 	/* while waiting for a data transfer */
 	STATUS_WAITING,
-	/* while sleeping because there is nothing to do */
+	/* while sleeping because there is nothing to do, but looking for tasks to do */
+	STATUS_SLEEPING_SCHEDULING,
+	/* while sleeping because there is nothing to do, and not even scheduling */
 	STATUS_SLEEPING
 };
 

+ 4 - 2
src/core/sched_ctx.c

@@ -2168,7 +2168,8 @@ unsigned _starpu_sched_ctx_last_worker_awake(struct _starpu_worker *worker)
 	 * awake. In the worst case, both workers will follow this pessimistic
 	 * path and perform one more scheduling loop */
 	STARPU_HG_DISABLE_CHECKING(_starpu_config.workers[worker->workerid].status);
-	STARPU_ASSERT(_starpu_config.workers[worker->workerid].status == STATUS_SLEEPING);
+	STARPU_ASSERT(_starpu_config.workers[worker->workerid].status == STATUS_SLEEPING
+	           || _starpu_config.workers[worker->workerid].status == STATUS_SLEEPING_SCHEDULING);
 	STARPU_HG_ENABLE_CHECKING(_starpu_config.workers[worker->workerid].status);
 	struct _starpu_sched_ctx_list_iterator list_it;
 
@@ -2202,7 +2203,8 @@ unsigned _starpu_sched_ctx_last_worker_awake(struct _starpu_worker *worker)
 					 * pessimistic path and assume that they are
 					 * the last worker awake */
 					STARPU_HG_DISABLE_CHECKING(_starpu_config.workers[workerid].status);
-					const int cond = _starpu_config.workers[workerid].status != STATUS_SLEEPING;
+					const int cond = _starpu_config.workers[workerid].status != STATUS_SLEEPING
+					              && _starpu_config.workers[workerid].status != STATUS_SLEEPING_SCHEDULING;
 					STARPU_HG_ENABLE_CHECKING(_starpu_config.workers[workerid].status);
 
 					if (cond)

+ 3 - 2
src/core/workers.c

@@ -2363,7 +2363,7 @@ static int starpu_wakeup_worker_locked(int workerid, starpu_pthread_cond_t *sche
 #ifdef STARPU_SIMGRID
 	starpu_pthread_queue_broadcast(&_starpu_simgrid_task_queue[workerid]);
 #endif
-	if (_starpu_config.workers[workerid].status == STATUS_SCHEDULING)
+	if (_starpu_config.workers[workerid].status == STATUS_SCHEDULING || _starpu_config.workers[workerid].status == STATUS_SLEEPING_SCHEDULING)
 	{
 		_starpu_config.workers[workerid].state_keep_awake = 1;
 		return 0;
@@ -2672,7 +2672,8 @@ int starpu_wake_worker_relax_light(int workerid)
 		while (!worker->state_relax_refcnt)
 		{
 			/* Attempt a fast path if the worker is not really asleep */
-			if (_starpu_config.workers[workerid].status == STATUS_SCHEDULING)
+			if (_starpu_config.workers[workerid].status == STATUS_SCHEDULING
+			 || _starpu_config.workers[workerid].status == STATUS_SLEEPING_SCHEDULING)
 			{
 				_starpu_config.workers[workerid].state_keep_awake = 1;
 				STARPU_PTHREAD_MUTEX_UNLOCK_SCHED(&worker->sched_mutex);

+ 10 - 3
src/drivers/driver_common/driver_common.c

@@ -319,8 +319,11 @@ void _starpu_driver_update_job_feedback(struct _starpu_job *j, struct _starpu_wo
 
 static void _starpu_worker_set_status_scheduling(int workerid)
 {
-	if (_starpu_worker_get_status(workerid) != STATUS_SLEEPING
-		&& _starpu_worker_get_status(workerid) != STATUS_SCHEDULING)
+	if (_starpu_worker_get_status(workerid) == STATUS_SLEEPING)
+	{
+		_starpu_worker_set_status(workerid, STATUS_SLEEPING_SCHEDULING);
+	}
+	else if (_starpu_worker_get_status(workerid) != STATUS_SCHEDULING)
 	{
 		_STARPU_TRACE_WORKER_SCHEDULING_START;
 		_starpu_worker_set_status(workerid, STATUS_SCHEDULING);
@@ -329,7 +332,11 @@ static void _starpu_worker_set_status_scheduling(int workerid)
 
 static void _starpu_worker_set_status_scheduling_done(int workerid)
 {
-	if (_starpu_worker_get_status(workerid) == STATUS_SCHEDULING)
+	if (_starpu_worker_get_status(workerid) == STATUS_SLEEPING_SCHEDULING)
+	{
+		_starpu_worker_set_status(workerid, STATUS_SLEEPING);
+	}
+	else if (_starpu_worker_get_status(workerid) == STATUS_SCHEDULING)
 	{
 		_STARPU_TRACE_WORKER_SCHEDULING_END;
 		_starpu_worker_set_status(workerid, STATUS_UNKNOWN);

+ 1 - 1
src/profiling/profiling.c

@@ -197,7 +197,7 @@ static void _starpu_worker_reset_profiling_info_with_lock(int workerid)
 	 * computation */
 	enum _starpu_worker_status status = _starpu_worker_get_status(workerid);
 
-	if (status == STATUS_SLEEPING)
+	if (status == STATUS_SLEEPING || status == STATUS_SLEEPING_SCHEDULING)
 	{
 		worker_registered_sleeping_start[workerid] = 1;
 		_starpu_clock_gettime(&sleeping_start_date[workerid]);