StarPU Internal Handbook
Loading...
Searching...
No Matches
knobs.h
Go to the documentation of this file.
1/* StarPU --- Runtime system for heterogeneous multicore architectures.
2 *
3 * Copyright (C) 2019-2022 Université de Bordeaux, CNRS (LaBRI UMR 5800), Inria
4 *
5 * StarPU is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU Lesser General Public License as published by
7 * the Free Software Foundation; either version 2.1 of the License, or (at
8 * your option) any later version.
9 *
10 * StarPU is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 *
14 * See the GNU Lesser General Public License in COPYING.LGPL for more details.
15 */
16
17/* Performance counters and configurable knobs */
18
19#ifndef __KNOBS_H__
20#define __KNOBS_H__
21
24#include <stdint.h>
25#include <starpu.h>
26#include <common/config.h>
27
28#pragma GCC visibility push(hidden)
29
31#define STARPU_ASSERT_PERF_COUNTER_SCOPE_DEFINED(t) STARPU_ASSERT( \
32 (t == starpu_perf_counter_scope_global) \
33 || (t == starpu_perf_counter_scope_per_worker) \
34 || (t == starpu_perf_counter_scope_per_codelet) \
35 )
36
37#define STARPU_ASSERT_PERF_COUNTER_TYPE_DEFINED(t) STARPU_ASSERT( \
38 (t == starpu_perf_counter_type_int32) \
39 || (t == starpu_perf_counter_type_int64) \
40 || (t == starpu_perf_counter_type_float) \
41 || (t == starpu_perf_counter_type_double) \
42 )
43
44#define _STARPU_PERF_COUNTER_ID_SCOPE_BITS 4
45
46#if defined(STARPU_VAL_COMPARE_AND_SWAP64) && defined (STARPU_ATOMIC_ADD64)
47#define STARPU_PERF_COUNTER_64
48#endif
49
51struct _starpu_worker;
52
53#define __STARPU_PERF_COUNTER_UPDATE_32BIT(OPNAME,OP,TYPENAME,TYPE) \
54static inline void _starpu_perf_counter_update_##OPNAME##_##TYPENAME(TYPE *ptr, TYPE value) \
55{ \
56 STARPU_ASSERT(sizeof(TYPE) == sizeof(uint32_t)); \
57 typedef uint32_t __attribute__((__may_alias__)) alias_uint32_t; \
58 typedef TYPE __attribute__((__may_alias__)) alias_##TYPE; \
59 \
60 uint32_t raw_old = *(uint32_t *)ptr; \
61 \
62 while(value OP *(alias_##TYPE*)&raw_old) \
63 { \
64 uint32_t raw_old_check = STARPU_VAL_COMPARE_AND_SWAP32((uint32_t *)ptr, raw_old, *(alias_uint32_t*)&value); \
65 if (raw_old_check == raw_old) \
66 break; \
67 raw_old = raw_old_check; \
68 } \
69}
70
71#ifdef STARPU_PERF_COUNTER_64
72typedef int64_t starpu_perf_counter_int64_t;
73typedef double starpu_perf_counter_double;
74#define __STARPU_PERF_COUNTER_UPDATE_64BIT(OPNAME,OP,TYPENAME,TYPE) \
75static inline void _starpu_perf_counter_update_##OPNAME##_##TYPENAME(TYPE *ptr, TYPE value) \
76{ \
77 STARPU_ASSERT(sizeof(TYPE) == sizeof(uint64_t)); \
78 typedef uint64_t __attribute__((__may_alias__)) alias_uint64_t; \
79 typedef TYPE __attribute__((__may_alias__)) alias_##TYPE; \
80 \
81 uint64_t raw_old = *(uint64_t *)ptr; \
82 \
83 while(value OP *(alias_##TYPE*)&raw_old) \
84 { \
85 uint64_t raw_old_check = STARPU_VAL_COMPARE_AND_SWAP64((uint64_t *)ptr, raw_old, *(alias_uint64_t*)&value); \
86 if (raw_old_check == raw_old) \
87 break; \
88 raw_old = raw_old_check; \
89 } \
90}
91#else
92/* No native 64bit atomic operation, revert to lower precision */
93typedef int32_t starpu_perf_counter_int64_t;
94typedef float starpu_perf_counter_double;
95#define __STARPU_PERF_COUNTER_UPDATE_64BIT(OPNAME,OP,TYPENAME,TYPE) \
96 __STARPU_PERF_COUNTER_UPDATE_32BIT(OPNAME,OP,TYPENAME,TYPE)
97#endif
98
99/* Atomic max */
100__STARPU_PERF_COUNTER_UPDATE_32BIT(max,>=,int32,int32_t);
101__STARPU_PERF_COUNTER_UPDATE_32BIT(max,>=,float,float);
102__STARPU_PERF_COUNTER_UPDATE_64BIT(max,>=,int64,starpu_perf_counter_int64_t);
103__STARPU_PERF_COUNTER_UPDATE_64BIT(max,>=,double,starpu_perf_counter_double);
104
105/* Atomic min */
106__STARPU_PERF_COUNTER_UPDATE_32BIT(min,<=,int32,int32_t);
107__STARPU_PERF_COUNTER_UPDATE_32BIT(min,<=,float,float);
108__STARPU_PERF_COUNTER_UPDATE_64BIT(min,<=,int64,starpu_perf_counter_int64_t);
109__STARPU_PERF_COUNTER_UPDATE_64BIT(min,<=,double,starpu_perf_counter_double);
110
111#undef __STARPU_PERF_COUNTER_UPDATE_32BIT
112#undef __STARPU_PERF_COUNTER_UPDATE_64BIT
113
115#define __STARPU_PERF_COUNTER_UPDATE_ACC_FLOAT(TYPENAME, TYPE) \
116static inline void _starpu_perf_counter_update_acc_##TYPENAME(TYPE *ptr, TYPE acc_value) \
117{ \
118 STARPU_ASSERT(sizeof(TYPE) == sizeof(uint32_t)); \
119 typedef uint32_t __attribute__((__may_alias__)) alias_uint32_t; \
120 typedef TYPE __attribute__((__may_alias__)) alias_float; \
121 uint32_t raw_old = *(uint32_t *)ptr; \
122 while (1) \
123 { \
124 TYPE value = acc_value + *(alias_float*)&raw_old; \
125 uint32_t raw_old_check = STARPU_VAL_COMPARE_AND_SWAP32((uint32_t *)ptr, raw_old, *(alias_uint32_t*)&value); \
126 if (raw_old_check == raw_old) \
127 break; \
128 raw_old = raw_old_check; \
129 } \
130}
131
133#ifdef STARPU_PERF_COUNTER_64
134static inline void _starpu_perf_counter_update_acc_double(double *ptr, double acc_value)
135{
136 STARPU_ASSERT(sizeof(double) == sizeof(uint64_t));
137 typedef uint64_t __attribute__((__may_alias__)) alias_uint64_t;
138 typedef double __attribute__((__may_alias__)) alias_double;
139 uint64_t raw_old = *(uint64_t *)ptr;
140 while (1)
141 {
142 double value = acc_value + *(alias_double*)&raw_old;
143 uint64_t raw_old_check = STARPU_VAL_COMPARE_AND_SWAP64((uint64_t *)ptr, raw_old, *(alias_uint64_t*)&value);
144 if (raw_old_check == raw_old)
145 break;
146 raw_old = raw_old_check;
147 }
148}
149#else
150__STARPU_PERF_COUNTER_UPDATE_ACC_FLOAT(double, starpu_perf_counter_double);
151#endif
152
153#ifdef STARPU_ATOMIC_ADD64
154#define STARPU_PERF_COUNTER_ADD64(ptr, val) STARPU_ATOMIC_ADD64((ptr), (val))
155#else
156#define STARPU_PERF_COUNTER_ADD64(ptr, val) STARPU_ATOMIC_ADD((ptr), (val))
157#endif
158
160{
161 int id;
162 const char *name;
163 const char *help;
164 enum starpu_perf_counter_type type;
165};
166
168{
169 enum starpu_perf_counter_scope scope;
170 int size;
171 int *index_array;
172};
173
175{
176 int32_t int32_val;
177 starpu_perf_counter_int64_t int64_val;
178 float float_val;
179 starpu_perf_counter_double double_val;
180};
181
183{
184 struct starpu_perf_counter_set *set;
185 void (*callback)(struct starpu_perf_counter_listener *listener, struct starpu_perf_counter_sample *sample, void *context);
186 void *user_arg;
187};
188
190{
191 enum starpu_perf_counter_scope scope;
192 struct starpu_perf_counter_listener *listener;
193 union starpu_perf_counter_value *value_array;
194 struct _starpu_spinlock lock;
195};
196
198{
199 struct
200 {
201 starpu_perf_counter_int64_t total_submitted;
202 starpu_perf_counter_int64_t peak_submitted;
203 starpu_perf_counter_int64_t current_submitted;
204 starpu_perf_counter_int64_t peak_ready;
205 starpu_perf_counter_int64_t current_ready;
206 starpu_perf_counter_int64_t total_executed;
207 starpu_perf_counter_double cumul_execution_time;
208 } task;
209};
210
211typedef void (*starpu_perf_counter_sample_updater)(struct starpu_perf_counter_sample *sample, void *context);
212
213static inline enum starpu_perf_counter_scope _starpu_perf_counter_id_get_scope(const int counter_id)
214{
215 STARPU_ASSERT(counter_id >= 0);
216 return counter_id & ((1 << _STARPU_PERF_COUNTER_ID_SCOPE_BITS) - 1);
217}
218
219static inline int _starpu_perf_counter_id_get_index(const int counter_id)
220{
221 STARPU_ASSERT(counter_id >= 0);
222 return counter_id >> _STARPU_PERF_COUNTER_ID_SCOPE_BITS;
223}
224
225static inline int _starpu_perf_counter_id_build(const enum starpu_perf_counter_scope scope, const int index)
226{
228 STARPU_ASSERT(index >= 0);
229 return (index << _STARPU_PERF_COUNTER_ID_SCOPE_BITS) | scope;
230}
231
232
233void _starpu_perf_counter_sample_init(struct starpu_perf_counter_sample *sample, enum starpu_perf_counter_scope scope);
234void _starpu_perf_counter_sample_exit(struct starpu_perf_counter_sample *sample);
235void _starpu_perf_counter_init(struct _starpu_machine_config *pconfig);
236void _starpu_perf_counter_exit(void);
237
238int _starpu_perf_counter_register(enum starpu_perf_counter_scope scope, const char *name, enum starpu_perf_counter_type type, const char *help);
239void _starpu_perf_counter_unregister_all_scopes(void);
240
241void _starpu_perf_counter_register_updater(enum starpu_perf_counter_scope scope, void (*updater)(struct starpu_perf_counter_sample *sample, void *context));
242
243void _starpu_perf_counter_update_global_sample(void);
244void _starpu_perf_counter_update_per_worker_sample(unsigned workerid);
245void _starpu_perf_counter_update_per_codelet_sample(struct starpu_codelet *cl);
246
247#define __STARPU_PERF_COUNTER_SAMPLE_SET_TYPED_VALUE(STRING, TYPE) \
248static inline void _starpu_perf_counter_sample_set_##STRING##_value(struct starpu_perf_counter_sample *sample, const int counter_id, const TYPE value) \
249{ \
250 STARPU_ASSERT(starpu_perf_counter_get_type_id(counter_id) == starpu_perf_counter_type_##STRING); \
251 STARPU_ASSERT(sample->listener != NULL && sample->listener->set != NULL); \
252 STARPU_ASSERT(_starpu_perf_counter_id_get_scope(counter_id) == sample->listener->set->scope); \
253 \
254 const struct starpu_perf_counter_set * const set = sample->listener->set; \
255 const int index = _starpu_perf_counter_id_get_index(counter_id); \
256 STARPU_ASSERT(index < set->size); \
257 if (set->index_array[index] > 0) \
258 { \
259 sample->value_array[index].STRING##_val = value; \
260 } \
261}
262
263__STARPU_PERF_COUNTER_SAMPLE_SET_TYPED_VALUE(int32, int32_t);
264__STARPU_PERF_COUNTER_SAMPLE_SET_TYPED_VALUE(int64, starpu_perf_counter_int64_t);
265__STARPU_PERF_COUNTER_SAMPLE_SET_TYPED_VALUE(float, float);
266__STARPU_PERF_COUNTER_SAMPLE_SET_TYPED_VALUE(double, starpu_perf_counter_double);
267
268#undef __STARPU_PERF_COUNTER_SAMPLE_SET_TYPED_VALUE
269
270#define __STARPU_PERF_COUNTER_REG(PREFIX, SCOPE, CTR, TYPESTRING, HELP) \
271 do \
272 { \
273 __##CTR = _starpu_perf_counter_register(SCOPE, \
274 PREFIX "." #CTR, starpu_perf_counter_type_ ## TYPESTRING, \
275 HELP); \
276 } \
277 while (0)
278
279/* global counter variables */
280extern starpu_perf_counter_int64_t _starpu_task__g_total_submitted__value;
281extern starpu_perf_counter_int64_t _starpu_task__g_peak_submitted__value;
282extern starpu_perf_counter_int64_t _starpu_task__g_current_submitted__value;
283extern starpu_perf_counter_int64_t _starpu_task__g_peak_ready__value;
284extern starpu_perf_counter_int64_t _starpu_task__g_current_ready__value;
285
286/* performance counter registration routines per modules */
287void _starpu__task_c__register_counters(void); /* module: task.c */
288
289
290/* -------------------------------------------------------------------- */
291/* Performance Steering */
292
293#define STARPU_ASSERT_PERF_KNOB_SCOPE_DEFINED(t) STARPU_ASSERT( \
294 (t == starpu_perf_knob_scope_global) \
295 || (t == starpu_perf_knob_scope_per_worker) \
296 || (t == starpu_perf_knob_scope_per_scheduler) \
297 )
298
299#define STARPU_ASSERT_PERF_KNOB_TYPE_DEFINED(t) STARPU_ASSERT( \
300 (t == starpu_perf_knob_type_int32) \
301 || (t == starpu_perf_knob_type_int64) \
302 || (t == starpu_perf_knob_type_float) \
303 || (t == starpu_perf_knob_type_double) \
304 )
305
306#define _STARPU_PERF_KNOBS_ID_SCOPE_BITS 4
307
308struct starpu_perf_knob;
309
311{
312 enum starpu_perf_knob_type type;
313 union
314 {
315 int32_t val_int32_t;
316 starpu_perf_counter_int64_t val_int64_t;
317 float val_float;
318 starpu_perf_counter_double val_double;
319 };
320};
321
323{
324 enum starpu_perf_knob_scope scope;
325 void (*set)(const struct starpu_perf_knob * const knob, void *context, const struct starpu_perf_knob_value * const value);
326 void (*get)(const struct starpu_perf_knob * const knob, void *context, struct starpu_perf_knob_value * const value);
327 int array_size;
328 struct starpu_perf_knob **array;
329};
330
332{
333 int id;
334 int id_in_group;
335 const char *name;
336 const char *help;
337 enum starpu_perf_knob_type type;
338 struct starpu_perf_knob_group *group;
339};
340
341#define __STARPU_PERF_KNOB_REG(PREFIX, SCOPE, CTR, TYPESTRING, HELP) \
342 do \
343 { \
344 __##CTR = _starpu_perf_knob_register(SCOPE, \
345 PREFIX "." #CTR, starpu_perf_knob_type_ ## TYPESTRING, \
346 HELP); \
347 } \
348 while (0)
349
350static inline int _starpu_perf_knob_id_get_scope(const int knob_id)
351{
352 STARPU_ASSERT(knob_id >= 0);
353 return knob_id & ((1 << _STARPU_PERF_KNOBS_ID_SCOPE_BITS) - 1);
354}
355
356static inline int _starpu_perf_knob_id_get_index(const int knob_id)
357{
358 STARPU_ASSERT(knob_id >= 0);
359 return knob_id >> _STARPU_PERF_KNOBS_ID_SCOPE_BITS;
360}
361
362static inline int _starpu_perf_knob_id_build(const enum starpu_perf_knob_scope scope, const int index)
363{
364 STARPU_ASSERT_PERF_KNOB_SCOPE_DEFINED(scope);
365 STARPU_ASSERT(index >= 0);
366 return (index << _STARPU_PERF_KNOBS_ID_SCOPE_BITS) | scope;
367}
368
369void _starpu_perf_knob_init(void);
370void _starpu_perf_knob_exit(void);
371
372struct starpu_perf_knob_group *_starpu_perf_knob_group_register(enum starpu_perf_knob_scope scope,
373 void (*set_func)(const struct starpu_perf_knob * const knob, void *context, const struct starpu_perf_knob_value * const value),
374 void (*get_func)(const struct starpu_perf_knob * const knob, void *context, struct starpu_perf_knob_value * const value));
375void _starpu_perf_knob_group_unregister(struct starpu_perf_knob_group *group);
376
377int _starpu_perf_knob_register(struct starpu_perf_knob_group *group, const char *name, enum starpu_perf_knob_type type, const char *help);
378void _starpu_perf_knob_unregister_all_scopes(void);
379
380/* performance knob registration routines per modules */
381void _starpu__workers_c__register_knobs(void); /* module: workers.c */
382void _starpu__task_c__register_knobs(void); /* module: task.c */
383void _starpu__dmda_c__register_knobs(void); /* module: dmda.c */
384void _starpu__workers_c__unregister_knobs(void); /* module: workers.c */
385void _starpu__task_c__unregister_knobs(void); /* module: task.c */
386void _starpu__dmda_c__unregister_knobs(void); /* module: dmda.c */
387
388#pragma GCC visibility pop
389
390#endif // __KNOBS_H__
#define __STARPU_PERF_COUNTER_UPDATE_ACC_FLOAT(TYPENAME, TYPE)
Definition knobs.h:115
#define STARPU_ASSERT_PERF_COUNTER_SCOPE_DEFINED(t)
Definition knobs.h:31
Definition knobs.h:160
Definition knobs.h:190
Definition knobs.h:168
Definition knobs.h:332
Definition knobs.h:311
Definition knobs.h:175
Definition starpu_spinlock.h:82
Definition workers.h:441
Definition workers.h:155
Definition knobs.h:183
Definition knobs.h:323