209
206
return (unsigned long long)sec * smpi_rastro_resolution() + pre;
212
static char *sample_location(int global, const char *file, int line)
209
/* ****************************** Functions related to the SMPI_SAMPLE_ macros ************************************/
211
int iters; /* amount of requested iterations */
212
int count; /* amount of iterations done so far */
213
double threshold; /* maximal stderr requested (if positive) */
214
double relstderr; /* observed stderr so far */
215
double mean; /* mean of benched times, to be used if the block is disabled */
216
double sum; /* sum of benched times (to compute the mean and stderr) */
217
double sum_pow2; /* sum of the square of the benched times (to compute the stderr) */
218
int benching; /* 1: we are benchmarking; 0: we have enough data, no bench anymore */
221
static char *sample_location(int global, const char *file, int line) {
215
223
return bprintf("%s:%d", file, line);
217
225
return bprintf("%s:%d:%d", file, line, smpi_process_index());
228
static int sample_enough_benchs(local_data_t *data) {
229
int res = data->count >= data->iters;
230
if (data->threshold>0.0) {
232
res = 0; // not enough data
233
if (data->relstderr > data->threshold)
234
res = 0; // stderr too high yet
236
XBT_DEBUG("%s (count:%d iter:%d stderr:%f thres:%f mean:%fs)",
237
(res?"enough benchs":"need more data"),
238
data->count, data->iters, data->relstderr, data->threshold, data->mean);
221
int smpi_sample_1(int global, const char *file, int line, int iters, double threshold)
242
void smpi_sample_1(int global, const char *file, int line, int iters, double threshold)
223
244
char *loc = sample_location(global, file, line);
224
245
local_data_t *data;
226
smpi_bench_end(); /* Take time from previous MPI call into account */
247
smpi_bench_end(); /* Take time from previous, unrelated computation into account */
228
249
samples = xbt_dict_new_homogeneous(free);
230
251
data = xbt_dict_get_or_null(samples, loc);
253
xbt_assert(threshold>0 || iters>0,
254
"You should provide either a positive amount of iterations to bench, or a positive maximal stderr (or both)");
232
255
data = (local_data_t *) xbt_new(local_data_t, 1);
235
258
data->sum_pow2 = 0.0;
236
259
data->iters = iters;
237
260
data->threshold = threshold;
261
data->benching = 1; // If we have no data, we need at least one
239
263
xbt_dict_set(samples, loc, data, NULL);
264
XBT_DEBUG("XXXXX First time ever on benched nest %s.",loc);
266
if (data->iters != iters || data->threshold != threshold) {
267
XBT_ERROR("Asked to bench block %s with different settings %d, %f is not %d, %f. How did you manage to give two numbers at the same line??",
268
loc, data->iters, data->threshold, iters,threshold);
272
// if we already have some data, check whether sample_2 should get one more bench or whether it should emulate the computation instead
273
data->benching = !sample_enough_benchs(data);
274
XBT_DEBUG("XXXX Re-entering the benched nest %s. %s",loc, (data->benching?"more benching needed":"we have enough data, skip computes"));
279
int smpi_sample_2(int global, const char *file, int line)
281
char *loc = sample_location(global, file, line);
284
xbt_assert(samples, "Y U NO use SMPI_SAMPLE_* macros? Stop messing directly with smpi_sample_* functions!");
285
data = xbt_dict_get(samples, loc);
286
XBT_DEBUG("sample2 %s",loc);
289
if (data->benching==1) {
290
// we need to run a new bench
291
XBT_DEBUG("benchmarking: count:%d iter:%d stderr:%f thres:%f; mean:%f",
292
data->count, data->iters, data->relstderr, data->threshold, data->mean);
296
// Enough data, no more bench (either we got enough data from previous visits to this benched nest, or we just ran one bench and need to bail out now that our job is done).
297
// Just sleep instead
298
XBT_DEBUG("No benchmark (either no need, or just ran one): count >= iter (%d >= %d) or stderr<thres (%f<=%f). apply the %fs delay instead",
299
data->count, data->iters, data->relstderr, data->threshold, data->mean);
300
smpi_execute(data->mean);
302
smpi_bench_begin(); // prepare to capture future, unrelated computations
246
int smpi_sample_2(int global, const char *file, int line)
248
char *loc = sample_location(global, file, line);
251
xbt_assert(samples, "You did something very inconsistent, didn't you?");
252
data = xbt_dict_get_or_null(samples, loc);
254
xbt_assert(data, "Please, do thing in order");
256
if (!data->started) {
257
if ((data->iters > 0 && data->count >= data->iters)
258
|| (data->count > 1 && data->threshold > 0.0 && data->relstderr <= data->threshold)) {
259
XBT_DEBUG("Perform some wait of %f", data->mean);
260
smpi_execute(data->mean);
270
smpi_process_simulated_start();
271
return data->started;
274
308
void smpi_sample_3(int global, const char *file, int line)
276
310
char *loc = sample_location(global, file, line);
277
311
local_data_t *data;
313
xbt_assert(samples, "Y U NO use SMPI_SAMPLE_* macros? Stop messing directly with smpi_sample_* functions!");
314
data = xbt_dict_get(samples, loc);
315
XBT_DEBUG("sample3 %s",loc);
317
if (data->benching==0) {
321
// ok, benchmarking this loop is over
322
xbt_os_timer_stop(smpi_process_timer());
278
325
double sample, n;
280
xbt_assert(samples, "You did something very inconsistent, didn't you?");
281
data = xbt_dict_get_or_null(samples, loc);
283
if(data && data->started && data->count < data->iters) {
284
sample = smpi_process_simulated_elapsed();
286
data->sum_pow2 += sample * sample;
287
n = (double)data->count;
288
data->mean = data->sum / n;
289
data->relstderr = sqrt((data->sum_pow2 / n - data->mean * data->mean) / n) / data->mean;
290
XBT_DEBUG("Average mean after %d steps is %f, relative standard error is %f (sample was %f)", data->count,
291
data->mean, data->relstderr, sample);
327
sample = xbt_os_timer_elapsed(smpi_process_timer());
329
data->sum_pow2 += sample * sample;
330
n = (double)data->count;
331
data->mean = data->sum / n;
332
data->relstderr = sqrt((data->sum_pow2 / n - data->mean * data->mean) / n) / data->mean;
333
if (!sample_enough_benchs(data)) {
334
data->mean = sample; // Still in benching process; We want sample_2 to simulate the exact time of this loop occurrence before leaving, not the mean over the history
296
void smpi_sample_flops(double flops)
298
smpi_execute_flops(flops);
336
XBT_DEBUG("Average mean after %d steps is %f, relative standard error is %f (sample was %f)", data->count,
337
data->mean, data->relstderr, sample);
339
// That's enough for now, prevent sample_2 to run the same code over and over
301
344
void *smpi_shared_malloc(size_t size, const char *file, int line)
303
346
char *loc = bprintf("%zu_%s_%d", (size_t)getpid(), file, line);