source: soft/giet_vm/applications/rosenfeld/include/clock.h

Last change on this file was 826, checked in by meunier, 7 years ago
  • Mise à jour NR2 et Rosenfeld
File size: 23.3 KB
Line 
1
2#ifndef _CLOCK_H_
3#define _CLOCK_H_
4
5#include <stdint.h>
6
7#include "nrc_os_config.h"
8#if TARGET_OS == LINUX
9    #include <x86intrin.h>
10    #include <sys/time.h>
11
12    typedef uint64_t cl_size_t;
13    #define MAX_CLOCK_VAL 0xFFFFFFFFFFFFFFFFLU
14#elif TARGET_OS == GIETVM
15    typedef uint32_t cl_size_t;
16    #define MAX_CLOCK_VAL 0xFFFFFFFF
17#endif
18
19/**
20 * The macros should be called in the following order:
21 * - CLOCK_DEC;
22 * - CLOCK_INIT(num_threads, num_steps);
23 * - CLOCK_APP_START;
24 * - CLOCK_APP_CREATE;
25 * - CLOCK_THREAD_START(thread_id);
26 * - Repeat num_runs times:
27 *     - CLOCK_THREAD_COMPUTE_START(thread_id;
28 *     - Repeat num_step times:
29 *         - CLOCK_THREAD_START_STEP(thread_id, step_id)
30 *         - CLOCK_THREAD_END_STEP(thread_id, step_id)
31 *     - CLOCK_THREAD_COMPUTE_END(thread_id);
32 *     - CLOCK_ACCUMULATE;
33 * - CLOCK_THREAD_END(thread_id)
34 * - CLOCK_APP_JOIN;
35 * - CLOCK_APP_END;
36 * - CLOCK_FINALIZE(num_threads);
37 * - PRINT_CLOCK;
38 * - CLOCK_FREE;
39 * In case of several runs, the THREAD_COMPUTE and all the THREAD_STEP resulting times
40 * are averaged over all the runs. The other times are kind of irrelevant.
41 * TODO: make a struct gathering all variables and change macros to functions
42 */
43
44
45static void local_sort_asc(cl_size_t tab[], int32_t size) {
46    cl_size_t tmp;
47    int32_t i, j;
48    for (i = 0; i < size; i++) {
49        cl_size_t min = tab[i];
50        int32_t jmin = i;
51        for (j = i + 1; j < size; j++) {
52            if (tab[j] < min) {
53                jmin = j;
54                min = tab[j];
55            }
56        }
57        tmp = tab[i];
58        tab[i] = min;
59        tab[jmin] = tmp;
60    }
61}
62
63
64
65#define CLOCK_DEC cl_size_t app_start;                   \
66                  cl_size_t app_end;                     \
67                  cl_size_t app_create;                  \
68                  cl_size_t app_join;                    \
69                  cl_size_t * thread_start;              \
70                  cl_size_t * thread_end;                \
71                  cl_size_t * thread_compute_start;      \
72                  cl_size_t * thread_compute_end;        \
73                  int32_t step_number;                  \
74                  int32_t clock_thread_num;             \
75                  int32_t clock_num_runs;               \
76                  cl_size_t ** thread_start_step;        \
77                  cl_size_t ** thread_end_step;          \
78                  cl_size_t global_thread_start;         \
79                  cl_size_t global_thread_end;           \
80                  cl_size_t global_thread_compute_start; \
81                  cl_size_t global_thread_compute_end;   \
82                  cl_size_t accumulated_thread_compute;  \
83                  cl_size_t * global_thread_start_step;  \
84                  cl_size_t * global_thread_end_step;    \
85                  cl_size_t * accumulated_thread_step;
86
87#if TARGET_OS == GIETVM
88    #define CLOCK(x)  ({ x = giet_proctime(); })
89#elif TARGET_OS == LINUX
90    /*#define CLOCK(x)  ({                      \
91            struct timeval full_time;         \
92            gettimeofday(&full_time, NULL);   \
93            x = (cl_size_t) ((full_time.tv_usec + full_time.tv_sec * 1000000)); \
94            }) */
95    #define CLOCK(x) ({ x = __rdtsc(); })
96#endif
97
98// x = number of threads, y = number of steps
99#define CLOCK_INIT(x, y) ({                                                           \
100    clock_thread_num = (x);                                                           \
101    step_number = (y);                                                                \
102    clock_num_runs = 0;                                                               \
103    global_thread_start = MAX_CLOCK_VAL;                                              \
104    global_thread_end = 0;                                                            \
105    global_thread_compute_start = MAX_CLOCK_VAL;                                      \
106    global_thread_compute_end = 0;                                                    \
107    accumulated_thread_compute = 0;                                                   \
108    if ((x) > 0) {                                                                    \
109        thread_start = (cl_size_t *) malloc(sizeof(cl_size_t) * (x));                 \
110        thread_end = (cl_size_t *) malloc(sizeof(cl_size_t) * (x));                   \
111        thread_compute_start = (cl_size_t *) malloc(sizeof(cl_size_t) * (x));         \
112        thread_compute_end = (cl_size_t *) malloc(sizeof(cl_size_t) * (x));           \
113        if ((y) > 0) {                                                                \
114            global_thread_start_step = (cl_size_t *) malloc(sizeof(cl_size_t) * (y)); \
115            global_thread_end_step = (cl_size_t *) malloc(sizeof(cl_size_t) * (y));   \
116            thread_start_step = (cl_size_t **) malloc(sizeof(cl_size_t *) * (y));     \
117            thread_end_step = (cl_size_t **) malloc(sizeof(cl_size_t *) * (y));       \
118            accumulated_thread_step = (cl_size_t *) malloc(sizeof(cl_size_t) * (y));  \
119            for (int32_t j = 0; j < (y); j++) {                                       \
120                global_thread_start_step[j] = MAX_CLOCK_VAL;                          \
121                global_thread_end_step[j] = 0;                                        \
122                accumulated_thread_step[j] = 0;                                       \
123                thread_start_step[j] = (cl_size_t *) malloc(sizeof(cl_size_t) * (x)); \
124                thread_end_step[j] = (cl_size_t *) malloc(sizeof(cl_size_t) * (x));   \
125            }                                                                         \
126        }                                                                             \
127    }                                                                                 \
128})
129
130
131#define CLOCK_APP_START               ({ CLOCK(app_start); })
132#define CLOCK_APP_END                 ({ CLOCK(app_end); })
133#define CLOCK_APP_CREATE              ({ CLOCK(app_create); })
134#define CLOCK_APP_JOIN                ({ CLOCK(app_join); })
135#define CLOCK_THREAD_START(x)         ({ CLOCK(thread_start[x]); })
136#define CLOCK_THREAD_END(x)           ({ CLOCK(thread_end[x]); })
137#define CLOCK_THREAD_COMPUTE_START(x) ({ CLOCK(thread_compute_start[x]); })
138#define CLOCK_THREAD_COMPUTE_END(x)   ({ CLOCK(thread_compute_end[x]); })
139#define CLOCK_THREAD_START_STEP(x, y) ({ CLOCK(thread_start_step[y][x]); })
140#define CLOCK_THREAD_END_STEP(x, y)   ({ CLOCK(thread_end_step[y][x]); })
141
142#define CLOCK_ACCUMULATE ({                                              \
143    for (int32_t i = 0; i < clock_thread_num; i++) {                     \
144        if (thread_compute_start[i] < global_thread_compute_start) {     \
145            global_thread_compute_start = thread_compute_start[i];       \
146        }                                                                \
147        if (thread_compute_end[i] > global_thread_compute_end) {         \
148            global_thread_compute_end = thread_compute_end[i];           \
149        }                                                                \
150        for (int32_t j = 0; j < step_number; j++) {                      \
151            if (thread_start_step[j][i] < global_thread_start_step[j]) { \
152                global_thread_start_step[j] = thread_start_step[j][i];   \
153            }                                                            \
154            if (thread_end_step[j][i] > global_thread_end_step[j]) {     \
155                global_thread_end_step[j] = thread_end_step[j][i];       \
156            }                                                            \
157        }                                                                \
158    }                                                                    \
159    for (int32_t j = 0; j < step_number; j++) {                          \
160        accumulated_thread_step[j] += (global_thread_end_step[j] - global_thread_start_step[j]); \
161        global_thread_start_step[j] = MAX_CLOCK_VAL;                     \
162        global_thread_end_step[j] = 0;                                   \
163    }                                                                    \
164    accumulated_thread_compute += (global_thread_compute_end - global_thread_compute_start); \
165    global_thread_compute_start = MAX_CLOCK_VAL;                         \
166    global_thread_compute_end = 0;                                       \
167    clock_num_runs++;                                                    \
168})
169
170
171#define CLOCK_FINALIZE ({                                                \
172    if (clock_num_runs == 0) {                                           \
173        CLOCK_ACCUMULATE;                                                \
174    }                                                                    \
175    for (int32_t i = 0; i < clock_thread_num; i++) {                     \
176        if (thread_start[i] < global_thread_start) {                     \
177            global_thread_start = thread_start[i];                       \
178        }                                                                \
179        if (thread_compute_start[i] < global_thread_compute_start) {     \
180            global_thread_compute_start = thread_compute_start[i];       \
181        }                                                                \
182        if (thread_end[i] > global_thread_end) {                         \
183            global_thread_end = thread_end[i];                           \
184        }                                                                \
185        if (thread_compute_end[i] > global_thread_compute_end) {         \
186            global_thread_compute_end = thread_compute_end[i];           \
187        }                                                                \
188        for (int32_t j = 0; j < step_number; j++) {                      \
189            if (thread_start_step[j][i] < global_thread_start_step[j]) { \
190                global_thread_start_step[j] = thread_start_step[j][i];   \
191            }                                                            \
192            if (thread_end_step[j][i] > global_thread_end_step[j]) {     \
193                global_thread_end_step[j] = thread_end_step[j][i];       \
194            }                                                            \
195        }                                                                \
196    }                                                                    \
197})
198
199
200#if TARGET_OS == LINUX
201
202#define PRINT_CLOCK ({                                                                                                        \
203    MCA_VERBOSE1(printf("Timestamps:\n"));                                                                                    \
204    if (clock_num_runs > 1) {                                                                                                 \
205        MCA_VERBOSE1(printf("(THREAD_COMPUTE_START, THREAD_COMPUTE_END, THREAD_START_STEPs and THREAD_END_STEPs)\n"));        \
206        MCA_VERBOSE1(printf("(are those of the last run)\n"));                                                                \
207    }                                                                                                                         \
208    MCA_VERBOSE1(printf("[APP_START]            : %llu\n", (long long unsigned int) app_start));                              \
209    MCA_VERBOSE1(printf("[APP_CREATE]           : %llu\n", (long long unsigned int) app_create));                             \
210    MCA_VERBOSE1(printf("[THREAD_START]         : %llu\n", (long long unsigned int) global_thread_start));                    \
211    MCA_VERBOSE1(printf("[THREAD_COMPUTE_START] : %llu\n", (long long unsigned int) global_thread_compute_start));            \
212    for (int32_t j = 0; j < step_number; j++) {                                                                               \
213        MCA_VERBOSE1(printf("[THREAD_START_STEP_%d]  : %llu\n", j, (long long unsigned int) global_thread_start_step[j]));    \
214        MCA_VERBOSE1(printf("[THREAD_END_STEP_%d]    : %llu\n", j, (long long unsigned int) global_thread_end_step[j]));      \
215    }                                                                                                                         \
216    MCA_VERBOSE1(printf("[THREAD_COMPUTE_END]   : %llu\n", (long long unsigned int) global_thread_compute_end));              \
217    MCA_VERBOSE1(printf("[THREAD_END]           : %llu\n", (long long unsigned int) global_thread_end));                      \
218    MCA_VERBOSE1(printf("[APP_JOIN]             : %llu\n", (long long unsigned int) app_join));                               \
219    MCA_VERBOSE1(printf("[APP_END]              : %llu\n", (long long unsigned int) app_end));                                \
220    MCA_VERBOSE1(printf("Durations (in cycles):\n"));                                                                         \
221    if (clock_num_runs > 1) {                                                                                                 \
222        MCA_VERBOSE1(printf("(PARALLEL_COMPUTE and THREAD_STEPs are averaged over %d runs)\n", clock_num_runs));              \
223    }                                                                                                                         \
224    MCA_VERBOSE1(printf("[TOTAL]                : %llu\n", (long long unsigned int) app_end - app_start));                    \
225    MCA_VERBOSE1(printf("[THREAD]               : %llu\n", (long long unsigned int) app_join - app_create));                  \
226    MCA_VERBOSE1(printf("[PARALLEL]             : %llu\n", (long long unsigned int) global_thread_end - global_thread_start));\
227    MCA_VERBOSE1(printf("[PARALLEL_COMPUTE]     : %llu\n", (long long unsigned int) accumulated_thread_compute / clock_num_runs)); \
228    for (int32_t j = 0; j < step_number; j++) {                                                                               \
229        MCA_VERBOSE1(printf("[THREAD_STEP_%d]        : %llu\n", j, (long long unsigned int) accumulated_thread_step[j] / clock_num_runs)); \
230    }                                                                                                                         \
231    MCA_VERBOSE1(printf("\n"));                                                                                               \
232    MCA_VERBOSE1(printf("*** All threads times output in a gnuplot data-style ***\n"));                                       \
233    local_sort_asc(thread_start, clock_thread_num);                                                                           \
234    local_sort_asc(thread_compute_start, clock_thread_num);                                                                   \
235    local_sort_asc(thread_compute_end, clock_thread_num);                                                                     \
236    local_sort_asc(thread_end, clock_thread_num);                                                                             \
237    for (int32_t j = 0; j < step_number; j++) {                                                                               \
238        local_sort_asc(thread_start_step[j], clock_thread_num);                                                               \
239        local_sort_asc(thread_end_step[j], clock_thread_num);                                                                 \
240    }                                                                                                                         \
241    MCA_VERBOSE1(printf("# cycle     thread_id\n"));                                                                          \
242    for (int32_t i = 0; i < clock_thread_num; i++) {                                                                          \
243        MCA_VERBOSE1(printf("%llu\t%d\n", (long long unsigned int) thread_start[i] - app_start, i));                          \
244        MCA_VERBOSE1(printf("%llu\t%d\n", (long long unsigned int) thread_compute_start[i] - app_start, i));                  \
245        for (int32_t j = 0; j < step_number; j++) {                                                                           \
246            MCA_VERBOSE1(printf("%llu\t%d\n", (long long unsigned int) thread_start_step[j][i] - app_start, i));              \
247            MCA_VERBOSE1(printf("%llu\t%d\n", (long long unsigned int) thread_end_step[j][i] - app_start, i));                \
248        }                                                                                                                     \
249        MCA_VERBOSE1(printf("%llu\t%d\n", (long long unsigned int) thread_compute_end[i] - app_start, i));                    \
250        MCA_VERBOSE1(printf("%llu\t%d\n", (long long unsigned int) thread_end[i] - app_start, i));                            \
251    }                                                                                                                         \
252})
253
254#elif TARGET_OS == GIETVM
255
256#define PRINT_CLOCK ({                                                                                           \
257    MCA_VERBOSE1(printf("Timestamps:\n"));                                                                       \
258    if (clock_num_runs > 1) {                                                                                    \
259        MCA_VERBOSE1(printf("(THREAD_COMPUTE_START, THREAD_COMPUTE_END, THREAD_START_STEPs and THREAD_END_STEPs)\n")); \
260        MCA_VERBOSE1(printf("(are those of the last run)\n"));                                                   \
261    }                                                                                                            \
262    MCA_VERBOSE1(printf("[APP_START]            : %d\n",  app_start));                                           \
263    MCA_VERBOSE1(printf("[APP_CREATE]           : %d\n", app_create));                                           \
264    MCA_VERBOSE1(printf("[THREAD_START]         : %d\n", global_thread_start));                                  \
265    MCA_VERBOSE1(printf("[THREAD_COMPUTE_START] : %d\n", global_thread_compute_start));                          \
266    for (int32_t j = 0; j < step_number; j++) {                                                                  \
267        MCA_VERBOSE1(printf("[THREAD_START_STEP_%d]  : %d\n", j, global_thread_start_step[j]));                  \
268        MCA_VERBOSE1(printf("[THREAD_END_STEP_%d]    : %d\n", j, global_thread_end_step[j]));                    \
269    }                                                                                                            \
270    MCA_VERBOSE1(printf("[THREAD_COMPUTE_END]   : %d\n", global_thread_compute_end));                            \
271    MCA_VERBOSE1(printf("[THREAD_END]           : %d\n", global_thread_end));                                    \
272    MCA_VERBOSE1(printf("[APP_JOIN]             : %d\n", app_join));                                             \
273    MCA_VERBOSE1(printf("[APP_END]              : %d\n", app_end));                                              \
274    MCA_VERBOSE1(printf("Durations (in cycles):\n"));                                                            \
275    if (clock_num_runs > 1) {                                                                                    \
276        MCA_VERBOSE1(printf("(PARALLEL_COMPUTE and THREAD_STEPs are averaged over %d runs)\n", clock_num_runs)); \
277    }                                                                                                            \
278    MCA_VERBOSE1(printf("[TOTAL]                : %d\n", app_end - app_start));                                  \
279    MCA_VERBOSE1(printf("[THREAD]               : %d\n", app_join - app_create));                                \
280    MCA_VERBOSE1(printf("[PARALLEL]             : %d\n", global_thread_end - global_thread_start));              \
281    MCA_VERBOSE1(printf("[PARALLEL_COMPUTE]     : %d\n", accumulated_thread_compute / clock_num_runs));          \
282    for (int32_t j = 0; j < step_number; j++) {                                                                  \
283        MCA_VERBOSE1(printf("[THREAD_STEP_%d]        : %d\n", j, accumulated_thread_step[j] / clock_num_runs));  \
284    }                                                                                                            \
285    MCA_VERBOSE1(printf("\n"));                                                                                  \
286    MCA_VERBOSE1(printf("*** All threads times output in a gnuplot data-style ***\n"));                          \
287    local_sort_asc(thread_start, clock_thread_num);                                                              \
288    local_sort_asc(thread_compute_start, clock_thread_num);                                                      \
289    local_sort_asc(thread_compute_end, clock_thread_num);                                                        \
290    local_sort_asc(thread_end, clock_thread_num);                                                                \
291    for (int32_t j = 0; j < step_number; j++) {                                                                  \
292        local_sort_asc(thread_start_step[j], clock_thread_num);                                                  \
293        local_sort_asc(thread_end_step[j], clock_thread_num);                                                    \
294    }                                                                                                            \
295    MCA_VERBOSE1(printf("# cycle     thread_id\n"));                                                             \
296    for (int32_t i = 0; i < clock_thread_num; i++) {                                                             \
297        MCA_VERBOSE1(printf("%d\t%d\n", thread_start[i] - app_start, i));                                        \
298        MCA_VERBOSE1(printf("%d\t%d\n", thread_compute_start[i] - app_start, i));                                \
299        for (int32_t j = 0; j < step_number; j++) {                                                              \
300            MCA_VERBOSE1(printf("%d\t%d\n", thread_start_step[j][i] - app_start, i));                            \
301            MCA_VERBOSE1(printf("%d\t%d\n", thread_end_step[j][i] - app_start, i));                              \
302        }                                                                                                        \
303        MCA_VERBOSE1(printf("%d\t%d\n", thread_compute_end[i] - app_start, i));                                  \
304        MCA_VERBOSE1(printf("%d\t%d\n", thread_end[i] - app_start, i));                                          \
305    }                                                                                                            \
306})
307
308
309#endif
310
311
312
313
314#define CLOCK_FREE ({                                   \
315    if (clock_thread_num > 0) {                         \
316        free(thread_start);                             \
317        free(thread_end);                               \
318        free(thread_compute_start);                     \
319        free(thread_compute_end);                       \
320        if (step_number > 0) {                          \
321            free(global_thread_start_step);             \
322            free(global_thread_end_step);               \
323            free(accumulated_thread_step);              \
324            for (int32_t j = 0; j < step_number; j++) { \
325                free(thread_start_step[j]);             \
326                free(thread_end_step[j]);               \
327            }                                           \
328            free(thread_start_step);                    \
329            free(thread_end_step);                      \
330        }                                               \
331    }                                                   \
332})
333
334
335
336
337#endif
338
Note: See TracBrowser for help on using the repository browser.