Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
7ab58fa992077f4c24f52b68ef46f47a557dbb72
[simgrid.git] / src / smpi / smpi_bench.c
1 /* Copyright (c) 2007, 2009, 2010. 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 #include "private.h"
8 #include "xbt/dict.h"
9 #include "xbt/sysdep.h"
10 #include "surf/surf.h"
11
12 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(smpi_bench, smpi,
13                                 "Logging specific to SMPI (benchmarking)");
14
15 xbt_dict_t allocs = NULL;       /* Allocated on first use */
16 xbt_dict_t samples = NULL;      /* Allocated on first use */
17
18 typedef struct {
19   int count;
20   char data[];
21 } shared_data_t;
22
23 typedef struct {
24   double time;
25   int count;
26   int max;
27   int started;
28 } local_data_t;
29
30 void smpi_bench_destroy(void)
31 {
32   if (allocs) {
33     xbt_dict_free(&allocs);
34   }
35   if (samples) {
36     xbt_dict_free(&samples);
37   }
38 }
39
40 static void smpi_execute_flops(double flops)
41 {
42   smx_action_t action;
43   smx_host_t host;
44   host = SIMIX_host_self();
45
46   DEBUG1("Handle real computation time: %f flops", flops);
47   action = SIMIX_req_host_execute("computation", host, flops);
48 #ifdef HAVE_TRACING
49   SIMIX_req_set_category (action, TRACE_internal_smpi_get_category());
50 #endif
51   SIMIX_req_host_execution_wait(action);
52   SIMIX_req_host_execution_destroy(action);
53 }
54
55 static void smpi_execute(double duration)
56 {
57   if (duration >= xbt_cfg_get_double(_surf_cfg_set, "smpi/cpu_threshold")) {
58     DEBUG1("Sleep for %f to handle real computation time", duration);
59     smpi_execute_flops(duration *
60                        xbt_cfg_get_double(_surf_cfg_set,
61                                           "smpi/running_power"));
62   }
63 }
64
65 void smpi_bench_begin(void)
66 {
67   xbt_os_timer_start(smpi_process_timer());
68 }
69
70 void smpi_bench_end(void)
71 {
72   xbt_os_timer_t timer = smpi_process_timer();
73
74   xbt_os_timer_stop(timer);
75   smpi_execute(xbt_os_timer_elapsed(timer));
76 }
77
78 unsigned int smpi_sleep(unsigned int secs)
79 {
80   smpi_execute((double) secs);
81   return secs;
82 }
83
84 int smpi_gettimeofday(struct timeval *tv, struct timezone *tz)
85 {
86   double now = SIMIX_get_clock();
87
88   if (tv) {
89     tv->tv_sec = (time_t) now;
90     tv->tv_usec = (suseconds_t) (now * 1e6);
91   }
92   return 0;
93 }
94
95 static char *sample_location(int global, const char *file, int line)
96 {
97   if (global) {
98     return bprintf("%s:%d", file, line);
99   } else {
100     return bprintf("%s:%d:%d", file, line, smpi_process_index());
101   }
102 }
103
104 void smpi_sample_1(int global, const char *file, int line, int max)
105 {
106   char *loc = sample_location(global, file, line);
107   local_data_t *data;
108
109   smpi_bench_end();     /* Take time from previous MPI call into account */
110   if (!samples) {
111     samples = xbt_dict_new();
112   }
113   data = xbt_dict_get_or_null(samples, loc);
114   if (!data) {
115     data = (local_data_t *) xbt_new(local_data_t, 1);
116     data->time = 0.0;
117     data->count = 0;
118     data->max = max;
119     data->started = 0;
120     xbt_dict_set(samples, loc, data, &free);
121   }
122   free(loc);
123 }
124
125 int smpi_sample_2(int global, const char *file, int line)
126 {
127   char *loc = sample_location(global, file, line);
128   local_data_t *data;
129
130   xbt_assert0(samples, "You did something very inconsistent, didn't you?");
131   data = xbt_dict_get_or_null(samples, loc);
132   if (!data) {
133     xbt_assert0(data, "Please, do thing in order");
134   }
135   if (!data->started) {
136     if (data->count < data->max) {
137       data->started = 1;
138       data->count++;
139     } else {
140       DEBUG1("Perform some wait of %f", data->time / (double) data->count);
141       smpi_execute(data->time / (double) data->count);
142     }
143   } else {
144     data->started = 0;
145   }
146   free(loc);
147   smpi_bench_begin();
148   smpi_process_simulated_start();
149   return data->started;
150 }
151
152 void smpi_sample_3(int global, const char *file, int line)
153 {
154   char *loc = sample_location(global, file, line);
155   local_data_t *data;
156
157   xbt_assert0(samples, "You did something very inconsistent, didn't you?");
158   data = xbt_dict_get_or_null(samples, loc);
159   if (!data || !data->started || data->count >= data->max) {
160     xbt_assert0(data, "Please, do thing in order");
161   }
162   smpi_bench_end();
163   data->time += smpi_process_simulated_elapsed();
164   DEBUG2("Average mean after %d steps is %f", data->count,
165          data->time / (double) data->count);
166 }
167
168 void smpi_sample_flops(double flops)
169 {
170   smpi_execute_flops(flops);
171 }
172
173 void *smpi_shared_malloc(size_t size, const char *file, int line)
174 {
175   char *loc = bprintf("%s:%d:%zu", file, line, size);
176   shared_data_t *data;
177
178   if (!allocs) {
179     allocs = xbt_dict_new();
180   }
181   data = xbt_dict_get_or_null(allocs, loc);
182   if (!data) {
183     data = (shared_data_t *) xbt_malloc0(sizeof(int) + size);
184     data->count = 1;
185     xbt_dict_set(allocs, loc, data, &free);
186   } else {
187     data->count++;
188   }
189   free(loc);
190   return data->data;
191 }
192
193 void smpi_shared_free(void *ptr)
194 {
195   shared_data_t *data = (shared_data_t *) ((int *) ptr - 1);
196   char *loc;
197
198   if (!allocs) {
199     WARN0("Cannot free: nothing was allocated");
200     return;
201   }
202   loc = xbt_dict_get_key(allocs, data);
203   if (!loc) {
204     WARN1("Cannot free: %p was not shared-allocated by SMPI", ptr);
205     return;
206   }
207   data->count--;
208   if (data->count <= 0) {
209     xbt_dict_remove(allocs, loc);
210   }
211 }