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

Last change on this file since 823 was 823, checked in by meunier, 8 years ago
  • Improved scripts for simulations and graphes
  • Continued to clean up the lib nrc2 (from nrio2x.x to nrmem1.c)
  • Added a version (Fast - Parmerge - No stats)
File size: 17.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#endif
12
13/**
14 * The macros should be called in the following order:
15 * - CLOCK_DEC;
16 * - CLOCK_INIT(num_threads, num_steps);
17 * - CLOCK_APP_START;
18 * - CLOCK_APP_CREATE;
19 * - CLOCK_THREAD_START(thread_id);
20 * - Repeat num_runs times:
21 *     - CLOCK_THREAD_COMPUTE_START(thread_id;
22 *     - Repeat num_step times:
23 *         - CLOCK_THREAD_START_STEP(thread_id, step_id)
24 *         - CLOCK_THREAD_END_STEP(thread_id, step_id)
25 *     - CLOCK_THREAD_COMPUTE_END(thread_id);
26 *     - CLOCK_ACCUMULATE;
27 * - CLOCK_THREAD_END(thread_id)
28 * - CLOCK_APP_JOIN;
29 * - CLOCK_APP_END;
30 * - CLOCK_FINALIZE(num_threads);
31 * - PRINT_CLOCK;
32 * - CLOCK_FREE;
33 * In case of several runs, the THREAD_COMPUTE and all the THREAD_STEP resulting times
34 * are averaged over all the runs. The other times are kind of irrelevant.
35 * TODO: make a struct gathering all variables and change macros to functions
36 */
37
38
39static void local_sort_asc(uint64_t tab[], int32_t size) {
40    uint64_t tmp;
41    int32_t i, j;
42    for (i = 0; i < size; i++) {
43        uint64_t min = tab[i];
44        int32_t jmin = i;
45        for (j = i + 1; j < size; j++) {
46            if (tab[j] < min) {
47                jmin = j;
48                min = tab[j];
49            }
50        }
51        tmp = tab[i];
52        tab[i] = min;
53        tab[jmin] = tmp;
54    }
55}
56
57
58
59#define CLOCK_DEC uint64_t app_start;                   \
60                  uint64_t app_end;                     \
61                  uint64_t app_create;                  \
62                  uint64_t app_join;                    \
63                  uint64_t * thread_start;              \
64                  uint64_t * thread_end;                \
65                  uint64_t * thread_compute_start;      \
66                  uint64_t * thread_compute_end;        \
67                  int32_t step_number;                  \
68                  int32_t clock_thread_num;             \
69                  int32_t clock_num_runs;               \
70                  uint64_t ** thread_start_step;        \
71                  uint64_t ** thread_end_step;          \
72                  uint64_t global_thread_start;         \
73                  uint64_t global_thread_end;           \
74                  uint64_t global_thread_compute_start; \
75                  uint64_t global_thread_compute_end;   \
76                  uint64_t accumulated_thread_compute;  \
77                  uint64_t * global_thread_start_step;  \
78                  uint64_t * global_thread_end_step;    \
79                  uint64_t * accumulated_thread_step;
80
81#if TARGET_OS == GIETVM
82    #define CLOCK(x)  ({ x = giet_proctime(); })
83#elif TARGET_OS == LINUX
84    /*#define CLOCK(x)  ({                      \
85            struct timeval full_time;         \
86            gettimeofday(&full_time, NULL);   \
87            x = (uint64_t) ((full_time.tv_usec + full_time.tv_sec * 1000000)); \
88            }) */
89    #define CLOCK(x) ({ x = __rdtsc(); })
90#endif
91
92// x = number of threads, y = number of steps
93#define CLOCK_INIT(x, y) ({                                                         \
94    clock_thread_num = (x);                                                         \
95    step_number = (y);                                                              \
96    clock_num_runs = 0;                                                             \
97    global_thread_start = 0xFFFFFFFFFFFFFFFFLLU;                                    \
98    global_thread_end = 0;                                                          \
99    global_thread_compute_start = 0xFFFFFFFFFFFFFFFFLLU;                            \
100    global_thread_compute_end = 0;                                                  \
101    accumulated_thread_compute = 0;                                                 \
102    if ((x) > 0) {                                                                  \
103        thread_start = (uint64_t *) malloc(sizeof(uint64_t) * (x));                 \
104        thread_end = (uint64_t *) malloc(sizeof(uint64_t) * (x));                   \
105        thread_compute_start = (uint64_t *) malloc(sizeof(uint64_t) * (x));         \
106        thread_compute_end = (uint64_t *) malloc(sizeof(uint64_t) * (x));           \
107        if ((y) > 0) {                                                              \
108            global_thread_start_step = (uint64_t *) malloc(sizeof(uint64_t) * (y)); \
109            global_thread_end_step = (uint64_t *) malloc(sizeof(uint64_t) * (y));   \
110            thread_start_step = (uint64_t **) malloc(sizeof(uint64_t *) * (y));     \
111            thread_end_step = (uint64_t **) malloc(sizeof(uint64_t *) * (y));       \
112            accumulated_thread_step = (uint64_t *) malloc(sizeof(uint64_t) * (y));  \
113            for (int32_t j = 0; j < (y); j++) {                                     \
114                global_thread_start_step[j] = 0xFFFFFFFFFFFFFFFFLLU;                \
115                global_thread_end_step[j] = 0;                                      \
116                accumulated_thread_step[j] = 0;                                     \
117                thread_start_step[j] = (uint64_t *) malloc(sizeof(uint64_t) * (x)); \
118                thread_end_step[j] = (uint64_t *) malloc(sizeof(uint64_t) * (x));   \
119            }                                                                       \
120        }                                                                           \
121    }                                                                               \
122})
123
124
125#define CLOCK_APP_START               ({ CLOCK(app_start); })
126#define CLOCK_APP_END                 ({ CLOCK(app_end); })
127#define CLOCK_APP_CREATE              ({ CLOCK(app_create); })
128#define CLOCK_APP_JOIN                ({ CLOCK(app_join); })
129#define CLOCK_THREAD_START(x)         ({ CLOCK(thread_start[x]); })
130#define CLOCK_THREAD_END(x)           ({ CLOCK(thread_end[x]); })
131#define CLOCK_THREAD_COMPUTE_START(x) ({ CLOCK(thread_compute_start[x]); })
132#define CLOCK_THREAD_COMPUTE_END(x)   ({ CLOCK(thread_compute_end[x]); })
133#define CLOCK_THREAD_START_STEP(x, y) ({ CLOCK(thread_start_step[y][x]); })
134#define CLOCK_THREAD_END_STEP(x, y)   ({ CLOCK(thread_end_step[y][x]); })
135
136#define CLOCK_ACCUMULATE ({                                              \
137    for (int32_t i = 0; i < clock_thread_num; i++) {                     \
138        if (thread_compute_start[i] < global_thread_compute_start) {     \
139            global_thread_compute_start = thread_compute_start[i];       \
140        }                                                                \
141        if (thread_compute_end[i] > global_thread_compute_end) {         \
142            global_thread_compute_end = thread_compute_end[i];           \
143        }                                                                \
144        for (int32_t j = 0; j < step_number; j++) {                      \
145            if (thread_start_step[j][i] < global_thread_start_step[j]) { \
146                global_thread_start_step[j] = thread_start_step[j][i];   \
147            }                                                            \
148            if (thread_end_step[j][i] > global_thread_end_step[j]) {     \
149                global_thread_end_step[j] = thread_end_step[j][i];       \
150            }                                                            \
151        }                                                                \
152    }                                                                    \
153    for (int32_t j = 0; j < step_number; j++) {                          \
154        accumulated_thread_step[j] += (global_thread_end_step[j] - global_thread_start_step[j]); \
155        global_thread_start_step[j] = 0xFFFFFFFFFFFFFFFFLLU;             \
156        global_thread_end_step[j] = 0;                                   \
157    }                                                                    \
158    accumulated_thread_compute += (global_thread_compute_end - global_thread_compute_start); \
159    global_thread_compute_start = 0xFFFFFFFFFFFFFFFFLLU;                 \
160    global_thread_compute_end = 0;                                       \
161    clock_num_runs++;                                                    \
162})
163
164
165#define CLOCK_FINALIZE ({                                                \
166    if (clock_num_runs == 0) {                                           \
167        CLOCK_ACCUMULATE;                                                \
168    }                                                                    \
169    for (int32_t i = 0; i < clock_thread_num; i++) {                     \
170        if (thread_start[i] < global_thread_start) {                     \
171            global_thread_start = thread_start[i];                       \
172        }                                                                \
173        if (thread_compute_start[i] < global_thread_compute_start) {     \
174            global_thread_compute_start = thread_compute_start[i];       \
175        }                                                                \
176        if (thread_end[i] > global_thread_end) {                         \
177            global_thread_end = thread_end[i];                           \
178        }                                                                \
179        if (thread_compute_end[i] > global_thread_compute_end) {         \
180            global_thread_compute_end = thread_compute_end[i];           \
181        }                                                                \
182        for (int32_t j = 0; j < step_number; j++) {                      \
183            if (thread_start_step[j][i] < global_thread_start_step[j]) { \
184                global_thread_start_step[j] = thread_start_step[j][i];   \
185            }                                                            \
186            if (thread_end_step[j][i] > global_thread_end_step[j]) {     \
187                global_thread_end_step[j] = thread_end_step[j][i];       \
188            }                                                            \
189        }                                                                \
190    }                                                                    \
191})
192
193
194#define PRINT_CLOCK ({                                                                                                        \
195    MCA_VERBOSE1(printf("Timestamps:\n"));                                                                                    \
196    if (clock_num_runs > 1) {                                                                                                 \
197        MCA_VERBOSE1(printf("(THREAD_COMPUTE_START, THREAD_COMPUTE_END, THREAD_START_STEPs and THREAD_END_STEPs)\n"));        \
198        MCA_VERBOSE1(printf("(are those of the last run)\n"));                                                                \
199    }                                                                                                                         \
200    MCA_VERBOSE1(printf("[APP_START]            : %llu\n", app_start));                                                       \
201    MCA_VERBOSE1(printf("[APP_CREATE]           : %llu\n", app_create));                                                      \
202    MCA_VERBOSE1(printf("[THREAD_START]         : %llu\n", global_thread_start));                                             \
203    MCA_VERBOSE1(printf("[THREAD_COMPUTE_START] : %llu\n", global_thread_compute_start));                                     \
204    for (int32_t j = 0; j < step_number; j++) {                                                                               \
205        MCA_VERBOSE1(printf("[THREAD_START_STEP_%d]  : %llu\n", j, global_thread_start_step[j]));                             \
206        MCA_VERBOSE1(printf("[THREAD_END_STEP_%d]    : %llu\n", j, global_thread_end_step[j]));                               \
207    }                                                                                                                         \
208    MCA_VERBOSE1(printf("[THREAD_COMPUTE_END]   : %llu\n", global_thread_compute_end));                                       \
209    MCA_VERBOSE1(printf("[THREAD_END]           : %llu\n", global_thread_end));                                               \
210    MCA_VERBOSE1(printf("[APP_JOIN]             : %llu\n", app_join));                                                        \
211    MCA_VERBOSE1(printf("[APP_END]              : %llu\n", app_end));                                                         \
212    MCA_VERBOSE1(printf("Durations (in cycles):\n"));                                                                         \
213    if (clock_num_runs > 1) {                                                                                                 \
214        MCA_VERBOSE1(printf("(PARALLEL_COMPUTE and THREAD_STEPs are averaged over %d runs)\n", clock_num_runs));              \
215    }                                                                                                                         \
216    MCA_VERBOSE1(printf("[TOTAL]                : %llu\n", app_end - app_start));                                             \
217    MCA_VERBOSE1(printf("[THREAD]               : %llu\n", app_join - app_create));                                           \
218    MCA_VERBOSE1(printf("[PARALLEL]             : %llu\n", global_thread_end - global_thread_start));                         \
219    MCA_VERBOSE1(printf("[PARALLEL_COMPUTE]     : %llu\n", accumulated_thread_compute / clock_num_runs));                     \
220    for (int32_t j = 0; j < step_number; j++) {                                                                               \
221        MCA_VERBOSE1(printf("[THREAD_STEP_%d]        : %llu\n", j, accumulated_thread_step[j] / clock_num_runs));             \
222    }                                                                                                                         \
223    MCA_VERBOSE1(printf("\n"));                                                                                               \
224    MCA_VERBOSE1(printf("*** All threads times output in a gnuplot data-style ***\n"));                                       \
225    local_sort_asc(thread_start, clock_thread_num);                                                                           \
226    local_sort_asc(thread_compute_start, clock_thread_num);                                                                   \
227    local_sort_asc(thread_compute_end, clock_thread_num);                                                                     \
228    local_sort_asc(thread_end, clock_thread_num);                                                                             \
229    for (int32_t j = 0; j < step_number; j++) {                                                                               \
230        local_sort_asc(thread_start_step[j], clock_thread_num);                                                               \
231        local_sort_asc(thread_end_step[j], clock_thread_num);                                                                 \
232    }                                                                                                                         \
233    MCA_VERBOSE1(printf("# cycle     thread_id\n"));                                                                          \
234    for (int32_t i = 0; i < clock_thread_num; i++) {                                                                          \
235        MCA_VERBOSE1(printf("%llu\t%d\n", thread_start[i] - app_start, i));                                                   \
236        MCA_VERBOSE1(printf("%llu\t%d\n", thread_compute_start[i] - app_start, i));                                           \
237        for (int32_t j = 0; j < step_number; j++) {                                                                           \
238            MCA_VERBOSE1(printf("%llu\t%d\n", thread_start_step[j][i] - app_start, i));                                       \
239            MCA_VERBOSE1(printf("%llu\t%d\n", thread_end_step[j][i] - app_start, i));                                         \
240        }                                                                                                                     \
241        MCA_VERBOSE1(printf("%llu\t%d\n", thread_compute_end[i] - app_start, i));                                             \
242        MCA_VERBOSE1(printf("%llu\t%d\n", thread_end[i] - app_start, i));                                                     \
243    }                                                                                                                         \
244})
245
246               
247
248
249
250
251#define CLOCK_FREE ({                                   \
252    if (clock_thread_num > 0) {                         \
253        free(thread_start);                             \
254        free(thread_end);                               \
255        free(thread_compute_start);                     \
256        free(thread_compute_end);                       \
257        if (step_number > 0) {                          \
258            free(global_thread_start_step);             \
259            free(global_thread_end_step);               \
260            free(accumulated_thread_step);              \
261            for (int32_t j = 0; j < step_number; j++) { \
262                free(thread_start_step[j]);             \
263                free(thread_end_step[j]);               \
264            }                                           \
265            free(thread_start_step);                    \
266            free(thread_end_step);                      \
267        }                                               \
268    }                                                   \
269})
270
271
272
273
274#endif
275
Note: See TracBrowser for help on using the repository browser.