File: bench.h

package info (click to toggle)
simgrid 4.1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 39,192 kB
  • sloc: cpp: 124,913; ansic: 66,744; python: 8,560; java: 6,773; fortran: 6,079; f90: 5,123; xml: 4,587; sh: 2,194; perl: 1,436; makefile: 111; lisp: 49; javascript: 7; sed: 6
file content (165 lines) | stat: -rw-r--r-- 4,934 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
/* Copyright (c) 2013-2025. The SimGrid Team.  All rights reserved.         */

/* This program is free software; you can redistribute it and/or modify it
 * under the terms of the license (GNU LGPL) which comes with this package. */

/* Copy to src/include/xbt/ folder  */

/* Benchmarking a code block */

/* Use functions from bench.h to benchmark execution time of the desired block,
 * then Rhist.R script to read all timings and produce histograms
 * and finally inject.h to inject values instead of executing block*/

#ifndef __BENCH_H__
#define __BENCH_H__

#include <time.h>
#include <stdio.h>
#include <string.h>

/* Structure that has all benchmarking information for the block*/
typedef struct bench {
	struct timespec start_time;
	struct timespec end_time;
	int benchmarking;
	char block_id[256];
	char suffix[100];
	FILE* output;
}*bench_t;

extern bench_t get_mybench(void);
typedef bench_t (*get_bench_func_t)(void);

/* In order to divide nanoseconds and get result in seconds */
#define BILLION  1000000000L

/* Macros for benchmarking */
#define BENCH_BLOCK(block_id) for(bench_begin_block();bench_end_block(block_id);)
#define BENCH_EXTEND(block_id) xbt_bench_extend(block_id)

static inline void xbt_bench_init(char *tracefile);
static inline void bench_init_starpu(char *tracefile, bench_t *bench);

static inline void bench_begin_block();
static inline int bench_end_block(char* block_id);

static inline void xbt_bench_begin(char* block_id);
static inline int xbt_bench_end(char* block_id);

static inline void xbt_bench_extend(char* block_id);

/* Additional functions in order to manipulate with struct timespec */
static inline void xbt_diff_time(struct timespec* start, struct timespec* end, struct timespec* result_time);
static inline double xbt_get_time(struct timespec* timer);

/* Initializing SMPI benchmarking */
static inline void xbt_bench_init(char *tracefile)
{
	bench_t mybench = get_mybench();
	mybench->output = fopen(tracefile, "a+");
	if (mybench->output == NULL)
		printf("Error while opening the tracefile");
}

/* Initializing StarPU benchmarking */
static inline void bench_init_starpu(char *tracefile, bench_t *bench)
{
  *bench = (bench_t) malloc(sizeof(**bench));
  bench_t mybench = *bench;
  mybench->output = fopen(tracefile, "a+");
  if (mybench->output == NULL)
		printf("Error while opening the tracefile");
}

/* Start benchmarking using macros */
static inline void bench_begin_block()
{
	bench_t mybench = get_mybench();
	clock_gettime(CLOCK_REALTIME, &mybench->start_time);
	mybench->benchmarking = 1; // Only benchmarking once
}

/* End benchmarking using macros */
static inline int bench_end_block(char* block_id)
{
	bench_t mybench = get_mybench();
	if (mybench->benchmarking > 0)
	{
		mybench->benchmarking--;
		return 1;
	}
	else
	{
		clock_gettime(CLOCK_REALTIME, &mybench->end_time);
		struct timespec interval;
		xbt_diff_time(&mybench->start_time, &mybench->end_time, &interval);
		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));
		return 0;
	}
}

/* Start SMPI benchmarking */
static inline void xbt_bench_begin(char* block_id)
{
	bench_t mybench = get_mybench();
	if(block_id != NULL)
		strcpy (mybench->block_id, block_id);
	else
		strcpy (mybench->block_id, "");
	clock_gettime(CLOCK_REALTIME, &mybench->start_time);
	mybench->benchmarking = 1; // Only benchmarking once
}

/* End SMPI benchmarking */
static inline int xbt_bench_end(char* block_id)
{
	bench_t mybench = get_mybench();

	clock_gettime(CLOCK_REALTIME, &mybench->end_time);
	struct timespec interval;
	xbt_diff_time(&mybench->start_time, &mybench->end_time, &interval);

	if(mybench->suffix != NULL)
	{
		strcat (mybench->block_id, mybench->suffix);
		strcpy (mybench->suffix, "");
	}
	if(block_id != NULL)
		strcat (mybench->block_id, block_id);
	if(mybench->block_id == NULL)
		strcat (mybench->block_id, "NONAME");

	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));
	return 0;
}

/* Extending the block_id name*/
static inline void xbt_bench_extend(char* block_id)
{
	bench_t mybench = get_mybench();
	strcpy (mybench->suffix, block_id);
}

/* Calculating time difference */
static inline void xbt_diff_time(struct timespec* start, struct timespec* end,	struct timespec* result_time)
{
	if ((end->tv_nsec - start->tv_nsec) < 0)
	{
		result_time->tv_sec = end->tv_sec - start->tv_sec - 1;
		result_time->tv_nsec = (double) BILLION + end->tv_nsec - start->tv_nsec;
	}
	else
	{
		result_time->tv_sec = end->tv_sec - start->tv_sec;
		result_time->tv_nsec = end->tv_nsec - start->tv_nsec;
	}
}

/* Printing time in "double" format */
static inline double xbt_get_time(struct timespec* timer)
{
	return timer->tv_sec + (double) (timer->tv_nsec / (double) BILLION);
}

#endif //__BENCH_H__