4 #ifndef SURF_MODEL_CPUTI_H_
5 #define SURF_MODEL_CPUTI_H_
7 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_cpu_tii, surf,
8 "Logging specific to the SURF CPU TRACE INTEGRATION module");
10 static std::vector<CpuTiActionPtr>
11 cpu_ti_running_action_set_that_does_not_need_being_checked;
12 static std::vector<CpuTiPtr> cpu_ti_modified_cpu;
13 static std::vector<CpuTiActionPtr> cpu_ti_action_heap;
18 static double surf_cpu_ti_integrate_trace(surf_cpu_ti_tgmr_t trace,
22 static double surf_cpu_ti_solve_trace(surf_cpu_ti_tgmr_t trace, double a,
24 static double surf_cpu_ti_solve_trace_somewhat_simple(surf_cpu_ti_tgmr_t
28 static void surf_cpu_ti_free_tmgr(surf_cpu_ti_tgmr_t trace);
30 static double surf_cpu_ti_integrate_trace_simple(surf_cpu_ti_trace_t trace,
32 static double surf_cpu_ti_integrate_trace_simple_point(surf_cpu_ti_trace_t
34 static double surf_cpu_ti_solve_trace_simple(surf_cpu_ti_trace_t trace,
35 double a, double amount);
36 static int surf_cpu_ti_binary_search(double *array, double a, int low,
39 static void surf_cpu_ti_free_trace(surf_cpu_ti_trace_t trace)
41 xbt_free(trace->time_points);
42 xbt_free(trace->integral);
46 static void surf_cpu_ti_free_tmgr(surf_cpu_ti_tgmr_t trace)
49 surf_cpu_ti_free_trace(trace->trace);
53 static surf_cpu_ti_trace_t surf_cpu_ti_trace_new(tmgr_trace_t power_trace)
55 surf_cpu_ti_trace_t trace;
61 trace = xbt_new0(s_surf_cpu_ti_trace_t, 1);
62 trace->time_points = (double*) xbt_malloc0(sizeof(double) *
63 (xbt_dynar_length(power_trace->s_list.event_list) + 1));
64 trace->integral = (double*) xbt_malloc0(sizeof(double) *
65 (xbt_dynar_length(power_trace->s_list.event_list) + 1));
66 trace->nb_points = xbt_dynar_length(power_trace->s_list.event_list);
67 xbt_dynar_foreach(power_trace->s_list.event_list, cpt, val) {
68 trace->time_points[i] = time;
69 trace->integral[i] = integral;
70 integral += val.delta * val.value;
74 trace->time_points[i] = time;
75 trace->integral[i] = integral;
80 * \brief Integrate trace
82 * Wrapper around surf_cpu_integrate_trace_simple() to get
85 * \param trace Trace structure.
86 * \param a Begin of interval
87 * \param b End of interval
88 * \return the integrate value. -1 if an error occurs.
90 static double surf_cpu_ti_integrate_trace(surf_cpu_ti_tgmr_t trace,
98 if ((a < 0.0) || (a > b)) {
100 ("Error, invalid integration interval [%.2f,%.2f]. You probably have a task executing with negative computation amount. Check your code.",
107 if (trace->type == TRACE_FIXED) {
108 return ((b - a) * trace->value);
111 if (ceil(a / trace->last_time) == a / trace->last_time)
112 a_index = 1 + (int) (ceil(a / trace->last_time));
114 a_index = (int) (ceil(a / trace->last_time));
116 b_index = (int) (floor(b / trace->last_time));
118 if (a_index > b_index) { /* Same chunk */
119 return surf_cpu_ti_integrate_trace_simple(trace->trace,
121 1) * trace->last_time,
127 first_chunk = surf_cpu_ti_integrate_trace_simple(trace->trace,
132 middle_chunk = (b_index - a_index) * trace->total;
133 last_chunk = surf_cpu_ti_integrate_trace_simple(trace->trace,
139 XBT_DEBUG("first_chunk=%.2f middle_chunk=%.2f last_chunk=%.2f\n",
140 first_chunk, middle_chunk, last_chunk);
142 return (first_chunk + middle_chunk + last_chunk);
146 * \brief Auxiliary function to calculate the integral between a and b.
147 * It simply calculates the integral at point a and b and returns the difference
149 * \param trace Trace structure
150 * \param a Initial point
151 * \param b Final point
154 static double surf_cpu_ti_integrate_trace_simple(surf_cpu_ti_trace_t trace,
157 return surf_cpu_ti_integrate_trace_simple_point(trace,
159 surf_cpu_ti_integrate_trace_simple_point(trace, a);
163 * \brief Auxiliary function to calculate the integral at point a.
164 * \param trace Trace structure
168 static double surf_cpu_ti_integrate_trace_simple_point(surf_cpu_ti_trace_t
175 surf_cpu_ti_binary_search(trace->time_points, a, 0,
176 trace->nb_points - 1);
177 integral += trace->integral[ind];
179 ("a %lf ind %d integral %lf ind + 1 %lf ind %lf time +1 %lf time %lf",
180 a, ind, integral, trace->integral[ind + 1], trace->integral[ind],
181 trace->time_points[ind + 1], trace->time_points[ind]);
182 double_update(&a_aux, trace->time_points[ind]);
185 ((trace->integral[ind + 1] -
186 trace->integral[ind]) / (trace->time_points[ind + 1] -
187 trace->time_points[ind])) * (a -
191 XBT_DEBUG("Integral a %lf = %lf", a, integral);
197 * \brief Calculate the time needed to execute "amount" on cpu.
199 * Here, amount can span multiple trace periods
201 * \param trace CPU trace structure
202 * \param a Initial time
203 * \param amount Amount to be executed
206 static double surf_cpu_ti_solve_trace(surf_cpu_ti_tgmr_t trace, double a,
211 double reduced_amount;
215 /* Fix very small negative numbers */
216 if ((a < 0.0) && (a > -EPSILON)) {
219 if ((amount < 0.0) && (amount > -EPSILON)) {
224 if ((a < 0.0) || (amount < 0.0)) {
226 ("Error, invalid parameters [a = %.2f, amount = %.2f]. You probably have a task executing with negative computation amount. Check your code.",
231 /* At this point, a and amount are positive */
233 if (amount < EPSILON)
236 /* Is the trace fixed ? */
237 if (trace->type == TRACE_FIXED) {
238 return (a + (amount / trace->value));
241 XBT_DEBUG("amount %lf total %lf", amount, trace->total);
242 /* Reduce the problem to one where amount <= trace_total */
243 quotient = (int) (floor(amount / trace->total));
244 reduced_amount = (trace->total) * ((amount / trace->total) -
245 floor(amount / trace->total));
246 reduced_a = a - (trace->last_time) * (int) (floor(a / trace->last_time));
248 XBT_DEBUG("Quotient: %d reduced_amount: %lf reduced_a: %lf", quotient,
249 reduced_amount, reduced_a);
251 /* Now solve for new_amount which is <= trace_total */
253 fprintf(stderr,"reduced_a = %.2f\n",reduced_a);
254 fprintf(stderr,"reduced_amount = %.2f\n",reduced_amount);
257 surf_cpu_ti_solve_trace_somewhat_simple(trace, reduced_a,
260 /* Re-map to the original b and amount */
261 b = (trace->last_time) * (int) (floor(a / trace->last_time)) +
262 (quotient * trace->last_time) + reduced_b;
267 * \brief Auxiliary function to solve integral
269 * Here, amount is <= trace->total
270 * and a <=trace->last_time
273 static double surf_cpu_ti_solve_trace_somewhat_simple(surf_cpu_ti_tgmr_t
277 double amount_till_end;
280 XBT_DEBUG("Solve integral: [%.2f, amount=%.2f]", a, amount);
282 surf_cpu_ti_integrate_trace(trace, a, trace->last_time);
284 fprintf(stderr,"amount_till_end=%.2f\n",amount_till_end);
287 if (amount_till_end > amount) {
288 b = surf_cpu_ti_solve_trace_simple(trace->trace, a, amount);
290 b = trace->last_time +
291 surf_cpu_ti_solve_trace_simple(trace->trace, 0.0,
292 amount - amount_till_end);
298 * \brief Auxiliary function to solve integral.
299 * It returns the date when the requested amount of flops is available
300 * \param trace Trace structure
301 * \param a Initial point
302 * \param amount Amount of flops
303 * \return The date when amount is available.
305 static double surf_cpu_ti_solve_trace_simple(surf_cpu_ti_trace_t trace,
306 double a, double amount)
311 integral_a = surf_cpu_ti_integrate_trace_simple_point(trace, a);
313 surf_cpu_ti_binary_search(trace->integral, integral_a + amount, 0,
314 trace->nb_points - 1);
315 time = trace->time_points[ind];
317 (integral_a + amount -
318 trace->integral[ind]) / ((trace->integral[ind + 1] -
319 trace->integral[ind]) /
320 (trace->time_points[ind + 1] -
321 trace->time_points[ind]));
327 * \brief Creates a new integration trace from a tmgr_trace_t
329 * \param power_trace CPU availability trace
330 * \param value Percentage of CPU power available (useful to fixed tracing)
331 * \param spacing Initial spacing
332 * \return Integration trace structure
334 static surf_cpu_ti_tgmr_t cpu_ti_parse_trace(tmgr_trace_t power_trace,
337 surf_cpu_ti_tgmr_t trace;
338 double total_time = 0.0;
341 trace = xbt_new0(s_surf_cpu_ti_tgmr_t, 1);
343 /* no availability file, fixed trace */
345 trace->type = TRACE_FIXED;
346 trace->value = value;
347 XBT_DEBUG("No availabily trace. Constant value = %lf", value);
351 /* only one point available, fixed trace */
352 if (xbt_dynar_length(power_trace->s_list.event_list) == 1) {
353 xbt_dynar_get_cpy(power_trace->s_list.event_list, 0, &val);
354 trace->type = TRACE_FIXED;
355 trace->value = val.value;
359 trace->type = TRACE_DYNAMIC;
360 trace->power_trace = power_trace;
362 /* count the total time of trace file */
363 xbt_dynar_foreach(power_trace->s_list.event_list, cpt, val) {
364 total_time += val.delta;
366 trace->trace = surf_cpu_ti_trace_new(power_trace);
367 trace->last_time = total_time;
369 surf_cpu_ti_integrate_trace_simple(trace->trace, 0, total_time);
371 XBT_DEBUG("Total integral %lf, last_time %lf ",
372 trace->total, trace->last_time);
378 * \brief Binary search in array.
379 * It returns the first point of the interval in which "a" is.
381 * \param a Value to search
382 * \param low Low bound to search in array
383 * \param high Upper bound to search in array
384 * \return Index of point
386 static int surf_cpu_ti_binary_search(double *array, double a, int low,
389 xbt_assert(low < high, "Wrong parameters: low (%d) should be smaller than"
390 " high (%d)", low, high);
394 mid = low + (high - low) / 2;
395 XBT_DEBUG("a %lf low %d high %d mid %d value %lf", a, low, high, mid,
403 while (low < high - 1);
412 CpuTiModel::CpuTiModel() : CpuModel("cpu_ti")
417 CpuTiPtr CpuTiModel::createResource(string name,
420 tmgr_trace_t powerTrace,
422 e_surf_resource_state_t stateInitial,
423 tmgr_trace_t stateTrace,
424 xbt_dict_t cpuProperties)
426 tmgr_trace_t empty_trace;
428 CpuTiActionPtr cpuAction;
429 xbt_assert(core==1,"Multi-core not handled with this model yet");
430 /*TOREPAIR: xbt_assert(!surf_cpu_resource_priv(surf_cpu_resource_by_name(name)),
431 "Host '%s' declared several times in the platform file",
433 CpuTiPtr cpu = new CpuTi(this, name, powerPeak, powerScale, powerTrace,
434 core, stateInitial, stateTrace, cpuProperties);
435 xbt_lib_set(host_lib, name.c_str(), SURF_CPU_LEVEL, cpu);
436 return (CpuTiPtr) xbt_lib_get_elm_or_null(host_lib, name.c_str());
439 CpuTiActionPtr CpuTiModel::createAction(double cost, bool failed)
441 return NULL;//new CpuTiAction(this, cost, failed);
444 void CpuTi::printCpuTiModel()
446 std::cout << getModel()->getName() << "<<plop"<< std::endl;
452 CpuTi::CpuTi(CpuTiModelPtr model, string name, double powerPeak,
453 double powerScale, tmgr_trace_t powerTrace, int core,
454 e_surf_resource_state_t stateInitial, tmgr_trace_t stateTrace,
455 xbt_dict_t properties) :
456 Cpu(model, name, properties), m_powerPeak(powerPeak), m_powerScale(powerScale),
457 m_stateCurrent(stateInitial) {
458 tmgr_trace_t empty_trace;
460 xbt_assert(core==1,"Multi-core not handled with this model yet");
461 XBT_DEBUG("power scale %lf", powerScale);
462 m_availTrace = cpu_ti_parse_trace(powerTrace, powerScale);
464 /*TOREPAIR:m_stateEvent = tmgr_history_add_trace(history, stateTrace, 0.0, 0, this);*/
465 if (powerTrace && xbt_dynar_length(powerTrace->s_list.event_list) > 1) {
466 // add a fake trace event if periodicity == 0
467 xbt_dynar_get_cpy(powerTrace->s_list.event_list,
468 xbt_dynar_length(powerTrace->s_list.event_list) - 1, &val);
469 /*TOREPAIR:if (val.delta == 0) {
470 empty_trace = tmgr_empty_trace_new();
472 tmgr_history_add_trace(history, empty_trace,
473 m_availTrace->last_time, 0, this);
478 CpuTiModelPtr CpuTi::getModel() {
479 return static_cast<CpuTiModelPtr>(p_model);
482 double CpuTi::getSpeed(double load)
484 return load * m_powerPeak;
487 double CpuTi::getAvailableSpeed()
496 double CpuTiAction::getRemains()
501 double CpuTiAction::getStartTime()
506 double CpuTiAction::getFinishTime()
511 #endif /* SURF_MODEL_CPUTI_H_ */