1 /* Copyright (c) 2013-2019. The SimGrid Team.
2 * All rights reserved. */
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. */
7 /* Copy to src/include/xbt/ folder */
9 /* Benchmarking a code block */
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*/
22 /* Structure that has all benchmarking information for the block*/
23 typedef struct bench {
24 struct timespec start_time;
25 struct timespec end_time;
32 extern bench_t get_mybench(void);
33 typedef bench_t (*get_bench_func_t)(void);
35 /* In order to divide nanoseconds and get result in seconds */
36 #define BILLION 1000000000L
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)
42 static inline void xbt_bench_init(char *tracefile);
43 static inline void bench_init_starpu(char *tracefile, bench_t *bench);
45 static inline void bench_begin_block();
46 static inline int bench_end_block(char* block_id);
48 static inline void xbt_bench_begin(char* block_id);
49 static inline int xbt_bench_end(char* block_id);
51 static inline void xbt_bench_extend(char* block_id);
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);
57 /* Initializing SMPI benchmarking */
58 static inline void xbt_bench_init(char *tracefile)
60 bench_t mybench = get_mybench();
61 mybench->output = fopen(tracefile, "a+");
62 if (mybench->output == NULL)
63 printf("Error while opening the tracefile");
67 /* Initializing StarPU benchmarking */
68 static inline void bench_init_starpu(char *tracefile, bench_t *bench)
70 *bench = (bench_t) malloc(sizeof(**bench));
71 bench_t mybench = *bench;
72 mybench->output = fopen(tracefile, "a+");
73 if (mybench->output == NULL)
74 printf("Error while opening the tracefile");
78 /* Start benchmarking using macros */
79 static inline void bench_begin_block()
81 bench_t mybench = get_mybench();
82 clock_gettime(CLOCK_REALTIME, &mybench->start_time);
83 mybench->benchmarking = 1; // Only benchmarking once
86 /* End benchmarking using macros */
87 static inline int bench_end_block(char* block_id)
89 bench_t mybench = get_mybench();
90 if (mybench->benchmarking > 0)
92 mybench->benchmarking--;
97 clock_gettime(CLOCK_REALTIME, &mybench->end_time);
98 struct timespec interval;
99 xbt_diff_time(&mybench->start_time, &mybench->end_time, &interval);
100 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));
105 /* Start SMPI benchmarking */
106 static inline void xbt_bench_begin(char* block_id)
108 bench_t mybench = get_mybench();
110 strcpy (mybench->block_id, block_id);
112 strcpy (mybench->block_id, "");
113 clock_gettime(CLOCK_REALTIME, &mybench->start_time);
114 mybench->benchmarking = 1; // Only benchmarking once
117 /* End SMPI benchmarking */
118 static inline int xbt_bench_end(char* block_id)
120 bench_t mybench = get_mybench();
122 clock_gettime(CLOCK_REALTIME, &mybench->end_time);
123 struct timespec interval;
124 xbt_diff_time(&mybench->start_time, &mybench->end_time, &interval);
126 if(mybench->suffix != NULL)
128 strcat (mybench->block_id, mybench->suffix);
129 strcpy (mybench->suffix, "");
132 strcat (mybench->block_id, block_id);
133 if(mybench->block_id == NULL)
134 strcat (mybench->block_id, "NONAME");
136 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));
140 /* Extending the block_id name*/
141 static inline void xbt_bench_extend(char* block_id)
143 bench_t mybench = get_mybench();
144 strcpy (mybench->suffix, block_id);
147 /* Calculating time difference */
148 static inline void xbt_diff_time(struct timespec* start, struct timespec* end, struct timespec* result_time)
150 if ((end->tv_nsec - start->tv_nsec) < 0)
152 result_time->tv_sec = end->tv_sec - start->tv_sec - 1;
153 result_time->tv_nsec = (double) BILLION + end->tv_nsec - start->tv_nsec;
157 result_time->tv_sec = end->tv_sec - start->tv_sec;
158 result_time->tv_nsec = end->tv_nsec - start->tv_nsec;
162 /* Printing time in "double" format */
163 static inline double xbt_get_time(struct timespec* timer)
165 return timer->tv_sec + (double) (timer->tv_nsec / (double) BILLION);