Browse Source

Add some basic online performance feedback capabilities: if the profiling is
enabled, we store the date of task submission, start and end, as well the
identifier of the worker that executed the task.

Cédric Augonnet 15 years ago
parent
commit
2e64948872

+ 2 - 1
Makefile.am

@@ -36,7 +36,8 @@ include_HEADERS = 				\
 	include/starpu_perfmodel.h		\
 	include/starpu_util.h			\
 	include/starpu_opencl.h			\
-	include/starpu_expert.h
+	include/starpu_expert.h			\
+	include/starpu_profiling.h
 
 noinst_HEADERS = \
 	include/pthread_win32/pthread.h		\

+ 39 - 0
include/starpu_profiling.h

@@ -0,0 +1,39 @@
+/*
+ * StarPU
+ * Copyright (C) INRIA 2008-2010 (see AUTHORS file)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * See the GNU Lesser General Public License in COPYING.LGPL for more details.
+ */
+
+#ifndef __STARPU_PROFILING_H__
+#define __STARPU_PROFILING_H__
+
+#include <errno.h>
+#include <starpu.h>
+
+/* -ENOSYS is returned in case the info is not available */
+struct starpu_task_profiling_info {
+	int64_t submit_time;
+	int64_t start_time;
+	int64_t end_time;
+	int workerid;
+};
+
+/* Enable the profiling and return the previous profiling status (0 if
+ * disabled, 1 if enabled). */
+unsigned starpu_enable_profiling(void);
+
+/* Disable the profiling and return the previous profiling status (0 if
+ * disabled, 1 if enabled). */
+unsigned starpu_disable_profiling(void);
+
+#endif // __STARPU_PROFILING_H__

+ 3 - 0
include/starpu_task.h

@@ -116,6 +116,8 @@ struct starpu_task {
 	 * set too. */ 
 	int regenerate;
 
+	struct starpu_task_profiling_info *profiling_info;
+
 	/* this is private to StarPU, do not modify. If the task is allocated
 	 * by hand (without starpu_task_create), this field should be set to
 	 * NULL. */
@@ -139,6 +141,7 @@ struct starpu_task {
 	.detach = 1,					\
 	.destroy = 0,					\
 	.regenerate = 0,				\
+	.profiling_info = NULL,				\
 	.starpu_private = NULL				\
 };
 

+ 4 - 2
src/Makefile.am

@@ -104,7 +104,8 @@ noinst_HEADERS = 						\
 	drivers/gordon/gordon_interface.h			\
 	drivers/cuda/driver_cuda.h				\
 	drivers/opencl/driver_opencl.h				\
-	drivers/opencl/driver_opencl_utils.h
+	drivers/opencl/driver_opencl_utils.h			\
+	profiling/profiling.h
 
 libstarpu_la_SOURCES = 						\
 	common/hash.c 						\
@@ -172,7 +173,8 @@ libstarpu_la_SOURCES = 						\
 	util/starpu_create_sync_task.c				\
 	util/starpu_cublas.c					\
 	util/file.c						\
-	debug/latency.c
+	debug/latency.c						\
+	profiling/profiling.c
 
 if STARPU_USE_CPU
 libstarpu_la_SOURCES += drivers/cpu/driver_cpu.c

+ 12 - 4
src/common/timing.c

@@ -16,6 +16,8 @@
 
 #include "timing.h"
 
+static double reference_start_time;
+
 #ifdef STARPU_HAVE_CLOCK_GETTIME
 
 #define TICK_DIFF(t1, t2) ((long long)((t2).ts.tv_sec*1e9 + (t2).ts.tv_nsec) + \
@@ -24,6 +26,7 @@
 
 void _starpu_timing_init(void)
 {
+	reference_start_time = _starpu_timing_now();
 }
 
 inline double _starpu_tick2usec(long long t)
@@ -47,10 +50,10 @@ inline double _starpu_timing_now(void)
 	starpu_tick_t tick_now;
 	STARPU_GET_TICK(tick_now);
 
-	return _starpu_tick2usec(((tick_now).ts.tv_sec*1e9) + (tick_now).ts.tv_nsec);
-}
-
+	double absolute_now = _starpu_tick2usec(((tick_now).ts.tv_sec*1e9) + (tick_now).ts.tv_nsec);
 
+	return (absolute_now - reference_start_time);
+}
 
 #else // STARPU_HAVE_CLOCK_GETTIME
 
@@ -92,6 +95,8 @@ void _starpu_timing_init(void)
       (double)(TICK_DIFF(t1, t2));
   }
 
+  reference_start_time = _starpu_timing_now();
+
   inited = 1;
 }
 
@@ -110,7 +115,10 @@ inline double _starpu_timing_now(void)
 	starpu_tick_t tick_now;
 	STARPU_GET_TICK(tick_now);
 
-	return _starpu_tick2usec(tick_now.tick);
+	double absolute_now =  _starpu_tick2usec(tick_now.tick);
+
+	return (absolute_now - reference_start_time);
+
 }
 
 #endif // STARPU_HAVE_CLOCK_GETTIME

+ 12 - 0
src/core/perfmodel/perfmodel.c

@@ -14,6 +14,9 @@
  * See the GNU Lesser General Public License in COPYING.LGPL for more details.
  */
 
+#include <starpu.h>
+#include <starpu_profiling.h>
+#include <common/config.h>
 #include <common/utils.h>
 #include <unistd.h>
 #include <sys/stat.h>
@@ -32,6 +35,15 @@ static unsigned calibrate_flag = 0;
 void _starpu_set_calibrate_flag(unsigned val)
 {
 	calibrate_flag = val;
+
+	if (calibrate_flag > 0)
+	{
+		starpu_enable_profiling();
+	}
+	else
+	{
+		starpu_disable_profiling();
+	}
 }
 
 unsigned _starpu_get_calibrate_flag(void)

+ 24 - 0
src/core/task.c

@@ -15,11 +15,13 @@
  */
 
 #include <starpu.h>
+#include <starpu_profiling.h>
 #include <core/workers.h>
 #include <core/jobs.h>
 #include <core/task.h>
 #include <common/config.h>
 #include <common/utils.h>
+#include <profiling/profiling.h>
 
 /* XXX this should be reinitialized when StarPU is shutdown (or we should make
  * sure that no task remains !) */
@@ -62,6 +64,8 @@ void starpu_task_init(struct starpu_task *task)
 
 	task->regenerate = 0;
 
+	task->profiling_info = NULL;
+
 	task->starpu_private = NULL;
 }
 
@@ -71,6 +75,13 @@ void starpu_task_deinit(struct starpu_task *task)
 {
 	STARPU_ASSERT(task);
 
+	/* If a buffer was allocated to store the profiling info, we free it. */
+	if (task->profiling_info)
+	{
+		free(task->profiling_info);
+		task->profiling_info = NULL;
+	}
+
 	starpu_job_t j = (struct starpu_job_s *)task->starpu_private;
 
 	if (j)
@@ -191,6 +202,19 @@ int starpu_task_submit(struct starpu_task *task)
 		_starpu_detect_implicit_data_deps(task);
 	}
 
+	/* If profiling is activated, we allocate a structure to store the
+	 * appropriate info. */
+	struct starpu_task_profiling_info *info;
+	info = _starpu_allocate_profiling_info_if_needed();
+	task->profiling_info = info;
+	
+	if (info)
+	{
+		info->submit_time = (int64_t)_starpu_timing_now();
+		info->start_time = -ENOSYS;
+		info->end_time = -ENOSYS;
+	}
+
 	/* internally, StarPU manipulates a starpu_job_t which is a wrapper around a
 	* task structure, it is possible that this job structure was already
 	* allocated, for instance to enforce task depenencies. */

+ 14 - 0
src/drivers/cpu/driver_cpu.c

@@ -15,6 +15,8 @@
  */
 
 #include <math.h>
+#include <starpu.h>
+#include <starpu_profiling.h>
 
 #include <common/utils.h>
 #include <core/debug.h>
@@ -56,6 +58,12 @@ static int execute_job_on_cpu(starpu_job_t j, struct starpu_worker_s *cpu_args)
 	if (calibrate_model || STARPU_BENCHMARK_COMM)
 		STARPU_GET_TICK(codelet_start);
 
+	struct starpu_task_profiling_info *profiling_info;
+	profiling_info = task->profiling_info;
+
+	if (profiling_info)
+		profiling_info->start_time = (int64_t)_starpu_timing_now();
+
 	cpu_args->status = STATUS_EXECUTING;
 	cl_func func = cl->cpu_func;
 	func(task->interface, task->cl_arg);
@@ -65,6 +73,12 @@ static int execute_job_on_cpu(starpu_job_t j, struct starpu_worker_s *cpu_args)
 	if (calibrate_model || STARPU_BENCHMARK_COMM)
 		STARPU_GET_TICK(codelet_end);
 
+	if (profiling_info)
+	{
+		profiling_info->end_time = (int64_t)_starpu_timing_now();
+		profiling_info->workerid = cpu_args->workerid;
+	}
+
 	STARPU_TRACE_END_CODELET_BODY(j);
 	cpu_args->status = STATUS_UNKNOWN;
 

+ 14 - 0
src/drivers/cuda/driver_cuda.c

@@ -14,6 +14,8 @@
  * See the GNU Lesser General Public License in COPYING.LGPL for more details.
  */
 
+#include <starpu.h>
+#include <starpu_profiling.h>
 #include <common/utils.h>
 #include <common/config.h>
 #include <core/debug.h>
@@ -127,6 +129,12 @@ static int execute_job_on_cuda(starpu_job_t j, struct starpu_worker_s *args)
 
 	STARPU_TRACE_START_CODELET_BODY(j);
 
+	struct starpu_task_profiling_info *profiling_info;
+	profiling_info = task->profiling_info;
+
+	if (profiling_info)
+		profiling_info->start_time = (int64_t)_starpu_timing_now();
+
 	args->status = STATUS_EXECUTING;
 	cl_func func = cl->cuda_func;
 	STARPU_ASSERT(func);
@@ -135,6 +143,12 @@ static int execute_job_on_cuda(starpu_job_t j, struct starpu_worker_s *args)
 
 	cl->per_worker_stats[args->workerid]++;
 
+	if (profiling_info)
+	{
+		profiling_info->end_time = (int64_t)_starpu_timing_now();
+		profiling_info->workerid = args->workerid;
+	}
+
 	STARPU_GET_TICK(codelet_end);
 
 	args->status = STATUS_UNKNOWN;

+ 14 - 0
src/drivers/opencl/driver_opencl.c

@@ -15,6 +15,8 @@
  */
 
 #include <math.h>
+#include <starpu.h>
+#include <starpu_profiling.h>
 #include <common/config.h>
 #include <common/utils.h>
 #include <core/debug.h>
@@ -375,6 +377,12 @@ static int _starpu_opencl_execute_job(starpu_job_t j, struct starpu_worker_s *ar
 
 	STARPU_TRACE_START_CODELET_BODY(j);
 
+	struct starpu_task_profiling_info *profiling_info;
+	profiling_info = task->profiling_info;
+
+	if (profiling_info)
+		profiling_info->start_time = (int64_t)_starpu_timing_now();
+
 	args->status = STATUS_EXECUTING;
 	cl_func func = cl->opencl_func;
 	STARPU_ASSERT(func);
@@ -383,6 +391,12 @@ static int _starpu_opencl_execute_job(starpu_job_t j, struct starpu_worker_s *ar
 
 	cl->per_worker_stats[args->workerid]++;
 
+	if (profiling_info)
+	{
+		profiling_info->end_time = (int64_t)_starpu_timing_now();
+		profiling_info->workerid = args->workerid;
+	}
+
 	STARPU_GET_TICK(codelet_end);
 
 	args->status = STATUS_UNKNOWN;

+ 51 - 0
src/profiling/profiling.c

@@ -0,0 +1,51 @@
+/*
+ * StarPU
+ * Copyright (C) INRIA 2008-2010 (see AUTHORS file)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * See the GNU Lesser General Public License in COPYING.LGPL for more details.
+ */
+
+#include <starpu.h>
+#include <starpu_profiling.h>
+#include <common/config.h>
+
+/* Disabled by default */
+static unsigned profiling = 0;
+
+unsigned starpu_enable_profiling(void)
+{
+	unsigned prev_value = profiling;
+	profiling = 1;
+
+	return prev_value;
+}
+
+unsigned starpu_disable_profiling(void)
+{
+	unsigned prev_value = profiling;
+	profiling = 0;
+
+	return prev_value;
+}
+
+struct starpu_task_profiling_info *_starpu_allocate_profiling_info_if_needed(void)
+{
+	struct starpu_task_profiling_info *info = NULL;
+
+	if (profiling)
+	{
+		info = calloc(1, sizeof(struct starpu_task_profiling_info));
+		STARPU_ASSERT(info);
+	}
+
+	return info;
+}

+ 26 - 0
src/profiling/profiling.h

@@ -0,0 +1,26 @@
+/*
+ * StarPU
+ * Copyright (C) INRIA 2008-2010 (see AUTHORS file)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * See the GNU Lesser General Public License in COPYING.LGPL for more details.
+ */
+
+#ifndef __PROFILING_H__
+#define __PROFILING_H__
+
+#include <starpu.h>
+#include <starpu_profiling.h>
+#include <common/config.h>
+
+struct starpu_task_profiling_info *_starpu_allocate_profiling_info_if_needed(void);
+
+#endif // __PROFILING_H__