Logo AND Algorithmique Numérique Distribuée

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