소스 검색

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 년 전
부모
커밋
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__