3 /* gras/emul.h - public interface to emulation support */
4 /* (specific parts for SG or RL) */
6 /* Copyright (c) 2003, 2004 Martin Quinson. All rights reserved. */
8 /* This program is free software; you can redistribute it and/or modify it
9 * under the terms of the license (GNU LGPL) which comes with this package. */
14 #include "xbt/misc.h" /* SG_BEGIN_DECL */
17 XBT_PUBLIC(void) gras_global_init(int *argc, char **argv);
18 XBT_PUBLIC(void) gras_create_environment(const char *file);
19 XBT_PUBLIC(void) gras_function_register(const char *name, void* code);
20 XBT_PUBLIC(void) gras_launch_application(const char *file);
21 XBT_PUBLIC(void) gras_clean(void);
22 XBT_PUBLIC(void) gras_main(void);
23 /** @addtogroup GRAS_emul
24 * @brief Code execution "emulation" and "virtualization".
26 * Emulation and virtualization words have a lot of different meanings in
27 * computer science. Here is what we mean, and what this module allows you
28 * to do (if it does not match your personal belives, I'm sorry):
30 * - Virtualization: Having some specific code for the simulation or for the reality
31 * - Emulation: Report within the simulator the execution time of your code
33 * \section GRAS_emul_virtualization Virtualization
35 * The whole idea of GRAS is to share the same code between the simulator
36 * and the real implementation. But it is sometimes impossible, such as
37 * when you want to deal with the OS. As an example, you may want to add
38 * some extra delay before initiating a communication in RL to ensure that
39 * the receiver is listening. This is usually useless in SG since you have
40 * a much better control on process launch time.
42 * This would be done with the following snipet:
43 * \verbatim if (gras_if_RL())
44 gras_os_sleep(1);\endverbatim
46 * Please note that those are real functions and not pre-processor
47 * defines. This is to ensure that the same object code can be linked
48 * against the SG library or the RL one without recompilation.
53 /** \brief Returns true only if the program runs on real life */
54 XBT_PUBLIC(int) gras_if_RL(void);
56 /** \brief Returns true only if the program runs within the simulator */
57 XBT_PUBLIC(int) gras_if_SG(void);
61 XBT_PUBLIC(int) gras_bench_always_begin(const char *location, int line);
62 XBT_PUBLIC(int) gras_bench_always_end(void);
63 XBT_PUBLIC(int) gras_bench_once_begin(const char *location, int line);
64 XBT_PUBLIC(int) gras_bench_once_end(void);
66 /** @addtogroup GRAS_emul
67 * \section GRAS_emul_timing Emulation
69 * For simulation accuracy, it is mandatory to report the execution time
70 * of your code into the simulator. For example, if your application is a
71 * parallel matrix multiplication, you naturally have to slow down the
72 * simulated hosts actually doing the computation.
74 * If you know beforehands how long each task will last, simply add a call
75 * to the gras_bench_fixed function described below. If not, you can have
76 * GRAS benchmarking your code automatically. Simply enclose the code to
77 * time between a macro GRAS_BENCH_*_BEGIN and GRAS_BENCH_*_END, and
78 * you're done. There is three pair of such macros, whose characteristics
79 * are summarized in the following table.
83 * <td><b>Name</b></td>
84 * <td><b>Run on host machine?</b></td>
85 * <td><b>Benchmarked?</b></td>
86 * <td><b>Corresponding time reported to simulation?</b></td>
89 * <td>GRAS_BENCH_ALWAYS_BEGIN()<br>
90 * GRAS_BENCH_ALWAYS_END()</td>
96 * <td>GRAS_BENCH_ONCE_RUN_ONCE_BEGIN()<br>
97 * GRAS_BENCH_ONCE_RUN_ONCE_END()</td>
98 * <td>Only first time</td>
99 * <td>Only first time</td>
100 * <td>Each time (with stored value)</td>
103 * <td>GRAS_BENCH_ONCE_RUN_ALWAYS_BEGIN()<br>
104 * GRAS_BENCH_ONCE_RUN_ALWAYS_END()</td>
106 * <td>Only first time</td>
107 * <td>Each time (with stored value)</td>
111 * As you can see, whatever macro pair you use, the corresponding value is
112 * repported to the simulator. After all, that's what those macro are
115 * The GRAS_BENCH_ALWAYS_* macros are the simplest ones. Each time the
116 * corresponding block is encountered, the corresponding code is executed
117 * and timed. Then, the simulated host is given the corresponding amount
120 * The GRAS_BENCH_ONCE_RUN_ONCE_* macros are good for cases where you know
121 * that your execution time is constant and where you don't care about the
122 * result in simulation mode. In our example, each sub-block
123 * multiplication takes exactly the same amount of work (time depends only
124 * on size, not on content), and the operation result can safely be
125 * ignored for algorithm result. Doing so allows you to considerably
126 * reduce the amount of computation needed when running on simulator.
128 * The GRAS_BENCH_ONCE_RUN_ALWAYS_* macros are good for cases where you
129 * know that each block will induce the same amount of work (you thus
130 * don't want to bench it each time), but you actually need the result (so
131 * you have to run it each time). You may ask why you don't use
132 * GRAS_BENCH_ONCE_RUN_ONCE_* macros in this case (why you save the
133 * benchmarking time). The timing operation is not very intrusive by
134 * itself, but it has to be done in an exclusive way between the several
135 * GRAS threads (protected by mutex). So, the day where there will be
136 * threads in GRAS, this will do a big difference. Ok, I agree. For now,
137 * it makes no difference.
141 * - Blocks are automatically differenciated using the filename and line
142 * position at which the *_BEGIN part was called. Don't put two of them
145 * - You cannot nest blocks. It would make no sense, either.
147 * - By the way, GRAS is not exactly designed for parallel algorithm such
148 * as parallel matrix multiplication but for distributed ones, you weirdo.
149 * But it's just an example ;)
153 /** \brief Start benchmarking this code block
155 #define GRAS_BENCH_ALWAYS_BEGIN() gras_bench_always_begin(__FILE__, __LINE__)
156 /** \brief Stop benchmarking this code block
158 #define GRAS_BENCH_ALWAYS_END() gras_bench_always_end()
160 /** \brief Start benchmarking this code block if it has never been benchmarked, run it in any case
161 * \hideinitializer */
162 #define GRAS_BENCH_ONCE_RUN_ALWAYS_BEGIN() gras_bench_once_begin(__FILE__, __LINE__)
163 /** \brief Stop benchmarking this part of the code
165 #define GRAS_BENCH_ONCE_RUN_ALWAYS_END() gras_bench_once_end()
167 /** \brief Start benchmarking this code block if it has never been benchmarked, ignore it if it was
169 #define GRAS_BENCH_ONCE_RUN_ONCE_BEGIN() if (gras_bench_once_begin(__FILE__, __LINE__)) {
170 /** \brief Stop benchmarking this part of the code
172 #define GRAS_BENCH_ONCE_RUN_ONCE_END() } gras_bench_once_end()
177 #endif /* GRAS_COND_H */