Logo AND Algorithmique Numérique Distribuée

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