Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Add missing SG_{BEGIN,END}_DECL.
[simgrid.git] / contrib / benchmarking_code_block / bench.h
1 /* Copy to src/include/xbt/ folder  */
2
3 /* Benchmarking a code block */
4
5 /* Use functions from bench.h to benchmark execution time of the desired block,
6  * then Rhist.R script to read all timings and produce histograms
7  * and finally inject.h to inject values instead of executing block*/
8
9 #ifndef __BENCH_H__
10 #define __BENCH_H__
11
12 #include <time.h>
13 #include <stdio.h>
14 #include <string.h>
15
16 /* Structure that has all benchmarking information for the block*/
17 typedef struct bench {
18         struct timespec start_time;
19         struct timespec end_time;
20         int benchmarking;
21         char block_id[256];
22         char suffix[100];
23         FILE* output;
24 }*bench_t;
25
26 extern bench_t get_mybench(void);
27 typedef bench_t (*get_bench_func_t)(void);
28
29 /* In order to divide nanoseconds and get result in seconds */
30 #define BILLION  1000000000L
31
32 /* Macros for benchmarking */
33 #define BENCH_BLOCK(block_id) for(bench_begin_block();bench_end_block(block_id);)
34 #define BENCH_EXTEND(block_id) xbt_bench_extend(block_id)
35
36 static inline void xbt_bench_init(char *tracefile);
37 static inline void bench_init_starpu(char *tracefile, bench_t *bench);
38
39 static inline void bench_begin_block();
40 static inline int bench_end_block(char* block_id);
41
42 static inline void xbt_bench_begin(char* block_id);
43 static inline int xbt_bench_end(char* block_id);
44
45 static inline void xbt_bench_extend(char* block_id);
46
47 /* Additional functions in order to manipulate with struct timespec */
48 static inline void xbt_diff_time(struct timespec* start, struct timespec* end, struct timespec* result_time);
49 static inline double xbt_get_time(struct timespec* timer);
50
51 /* Initializing SMPI benchmarking */
52 static inline void xbt_bench_init(char *tracefile)
53 {
54         bench_t mybench = get_mybench();
55         mybench->output = fopen(tracefile, "a+");
56         if (mybench->output == NULL)
57                 printf("Error while opening the tracefile");
58
59 }
60
61 /* Initializing StarPU benchmarking */
62 static inline void bench_init_starpu(char *tracefile, bench_t *bench)
63 {
64   *bench = (bench_t) malloc(sizeof(**bench));
65   bench_t mybench = *bench;
66   mybench->output = fopen(tracefile, "a+");
67   if (mybench->output == NULL)
68                 printf("Error while opening the tracefile");
69
70 }
71
72 /* Start benchmarking using macros */
73 static inline void bench_begin_block()
74 {
75         bench_t mybench = get_mybench();
76         clock_gettime(CLOCK_REALTIME, &mybench->start_time);
77         mybench->benchmarking = 1; // Only benchmarking once
78 }
79
80 /* End benchmarking using macros */
81 static inline int bench_end_block(char* block_id)
82 {
83         bench_t mybench = get_mybench();
84         if (mybench->benchmarking > 0)
85         {
86                 mybench->benchmarking--;
87                 return 1;
88         }
89         else
90         {
91                 clock_gettime(CLOCK_REALTIME, &mybench->end_time);
92                 struct timespec interval;
93                 xbt_diff_time(&mybench->start_time, &mybench->end_time, &interval);
94                 fprintf(mybench->output, "%s %lf %lf %lf\n", block_id, xbt_get_time(&mybench->start_time), xbt_get_time(&mybench->end_time), xbt_get_time(&interval));
95                 return 0;
96         }
97 }
98
99 /* Start SMPI benchmarking */
100 static inline void xbt_bench_begin(char* block_id)
101 {
102         bench_t mybench = get_mybench();
103         if(block_id != NULL)
104                 strcpy (mybench->block_id, block_id);
105         else
106                 strcpy (mybench->block_id, "");
107         clock_gettime(CLOCK_REALTIME, &mybench->start_time);
108         mybench->benchmarking = 1; // Only benchmarking once
109 }
110
111 /* End SMPI benchmarking */
112 static inline int xbt_bench_end(char* block_id)
113 {
114         bench_t mybench = get_mybench();
115
116         clock_gettime(CLOCK_REALTIME, &mybench->end_time);
117         struct timespec interval;
118         xbt_diff_time(&mybench->start_time, &mybench->end_time, &interval);
119
120         if(mybench->suffix != NULL)
121         {
122                 strcat (mybench->block_id, mybench->suffix);
123                 strcpy (mybench->suffix, "");
124         }
125         if(block_id != NULL)
126                 strcat (mybench->block_id, block_id);
127         if(mybench->block_id == NULL)
128                 strcat (mybench->block_id, "NONAME");
129
130         fprintf(mybench->output, "%s %lf %lf %lf\n", mybench->block_id, xbt_get_time(&mybench->start_time), xbt_get_time(&mybench->end_time), xbt_get_time(&interval));
131         return 0;
132 }
133
134 /* Extending the block_id name*/
135 static inline void xbt_bench_extend(char* block_id)
136 {
137         bench_t mybench = get_mybench();
138         strcpy (mybench->suffix, block_id);
139 }
140
141 /* Calculating time difference */
142 static inline void xbt_diff_time(struct timespec* start, struct timespec* end,  struct timespec* result_time)
143 {
144         if ((end->tv_nsec - start->tv_nsec) < 0)
145         {
146                 result_time->tv_sec = end->tv_sec - start->tv_sec - 1;
147                 result_time->tv_nsec = (double) BILLION + end->tv_nsec - start->tv_nsec;
148         }
149         else
150         {
151                 result_time->tv_sec = end->tv_sec - start->tv_sec;
152                 result_time->tv_nsec = end->tv_nsec - start->tv_nsec;
153         }
154 }
155
156 /* Printing time in "double" format */
157 static inline double xbt_get_time(struct timespec* timer)
158 {
159         return timer->tv_sec + (double) (timer->tv_nsec / (double) BILLION);
160 }
161
162 #endif //__BENCH_H__