helper_mct.c 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. /* StarPU --- Runtime system for heterogeneous multicore architectures.
  2. *
  3. * Copyright (C) 2013-2014, 2016 Université de Bordeaux
  4. * Copyright (C) 2013 INRIA
  5. * Copyright (C) 2013 Simon Archipoff
  6. *
  7. * StarPU is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU Lesser General Public License as published by
  9. * the Free Software Foundation; either version 2.1 of the License, or (at
  10. * your option) any later version.
  11. *
  12. * StarPU is distributed in the hope that it will be useful, but
  13. * WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  15. *
  16. * See the GNU Lesser General Public License in COPYING.LGPL for more details.
  17. */
  18. #include <starpu_sched_component.h>
  19. #include "helper_mct.h"
  20. /* Alpha, Beta and Gamma are MCT-specific values, which allows the
  21. * user to set more precisely the weight of each computing value.
  22. * Beta, for example, controls the weight of communications between
  23. * memories for the computation of the best component to choose.
  24. */
  25. #define _STARPU_SCHED_ALPHA_DEFAULT 1.0
  26. #define _STARPU_SCHED_BETA_DEFAULT 1.0
  27. #define _STARPU_SCHED_GAMMA_DEFAULT 1000.0
  28. #ifdef STARPU_USE_TOP
  29. static void param_modified(struct starpu_top_param* d)
  30. {
  31. /* Just to show parameter modification. */
  32. fprintf(stderr, "%s has been modified : %f\n",
  33. d->name, *(double*) d->value);
  34. }
  35. #endif /* !STARPU_USE_TOP */
  36. #ifdef STARPU_USE_TOP
  37. static const float alpha_minimum=0;
  38. static const float alpha_maximum=10.0;
  39. static const float beta_minimum=0;
  40. static const float beta_maximum=10.0;
  41. static const float gamma_minimum=0;
  42. static const float gamma_maximum=10000.0;
  43. static const float idle_power_minimum=0;
  44. static const float idle_power_maximum=10000.0;
  45. #endif /* !STARPU_USE_TOP */
  46. struct _starpu_mct_data *starpu_mct_init_parameters(struct starpu_sched_component_mct_data *params)
  47. {
  48. struct _starpu_mct_data * data = malloc(sizeof(*data));
  49. if (params)
  50. {
  51. data->alpha = params->alpha;
  52. data->beta = params->beta;
  53. data->_gamma = params->_gamma;
  54. data->idle_power = params->idle_power;
  55. }
  56. else
  57. {
  58. data->alpha = starpu_get_env_float_default("STARPU_SCHED_ALPHA", _STARPU_SCHED_ALPHA_DEFAULT);
  59. data->beta = starpu_get_env_float_default("STARPU_SCHED_BETA", _STARPU_SCHED_BETA_DEFAULT);
  60. data->_gamma = starpu_get_env_float_default("STARPU_SCHED_GAMMA", _STARPU_SCHED_GAMMA_DEFAULT);
  61. data->idle_power = starpu_get_env_float_default("STARPU_IDLE_POWER", 0.0);
  62. }
  63. #ifdef STARPU_USE_TOP
  64. starpu_top_register_parameter_float("MCT_ALPHA", &data->alpha,
  65. alpha_minimum, alpha_maximum, param_modified);
  66. starpu_top_register_parameter_float("MCT_BETA", &data->beta,
  67. beta_minimum, beta_maximum, param_modified);
  68. starpu_top_register_parameter_float("MCT_GAMMA", &data->_gamma,
  69. gamma_minimum, gamma_maximum, param_modified);
  70. starpu_top_register_parameter_float("MCT_IDLE_POWER", &data->idle_power,
  71. idle_power_minimum, idle_power_maximum, param_modified);
  72. #endif /* !STARPU_USE_TOP */
  73. return data;
  74. }
  75. /* compute predicted_end by taking into account the case of the predicted transfer and the predicted_end overlap
  76. */
  77. static double compute_expected_time(double now, double predicted_end, double predicted_length, double predicted_transfer)
  78. {
  79. STARPU_ASSERT(!isnan(now + predicted_end + predicted_length + predicted_transfer));
  80. STARPU_ASSERT(now >= 0.0 && predicted_end >= 0.0 && predicted_length >= 0.0 && predicted_transfer >= 0.0);
  81. /* TODO: actually schedule transfers */
  82. if (now + predicted_transfer < predicted_end)
  83. {
  84. /* We may hope that the transfer will be finished by
  85. * the start of the task. */
  86. predicted_transfer = 0;
  87. }
  88. else
  89. {
  90. /* The transfer will not be finished by then, take the
  91. * remainder into account */
  92. predicted_transfer -= (predicted_end - now);
  93. }
  94. predicted_end += predicted_transfer;
  95. predicted_end += predicted_length;
  96. return predicted_end;
  97. }
  98. double starpu_mct_compute_fitness(struct _starpu_mct_data * d, double exp_end, double min_exp_end, double max_exp_end, double transfer_len, double local_energy)
  99. {
  100. /* Note: the expected end includes the data transfer duration, which we want to be able to tune separately */
  101. return d->alpha * (exp_end - min_exp_end)
  102. + d->beta * transfer_len
  103. + d->_gamma * local_energy
  104. + d->_gamma * d->idle_power * (exp_end - max_exp_end);
  105. }
  106. int starpu_mct_compute_expected_times(struct starpu_sched_component *component, struct starpu_task *task,
  107. double *estimated_lengths, double *estimated_transfer_length, double *estimated_ends_with_task,
  108. double *min_exp_end_with_task, double *max_exp_end_with_task, int *suitable_components)
  109. {
  110. int nsuitable_components = 0;
  111. int i;
  112. for(i = 0; i < component->nchildren; i++)
  113. {
  114. struct starpu_sched_component * c = component->children[i];
  115. if(starpu_sched_component_execute_preds(c, task, estimated_lengths + i))
  116. {
  117. if(isnan(estimated_lengths[i]))
  118. /* The perfmodel had been purged since the task was pushed
  119. * onto the mct component. */
  120. continue;
  121. /* Estimated availability of worker */
  122. double estimated_end = c->estimated_end(c);
  123. double now = starpu_timing_now();
  124. if (estimated_end < now)
  125. estimated_end = now;
  126. estimated_transfer_length[i] = starpu_sched_component_transfer_length(c, task);
  127. estimated_ends_with_task[i] = compute_expected_time(now,
  128. estimated_end,
  129. estimated_lengths[i],
  130. estimated_transfer_length[i]);
  131. if(estimated_ends_with_task[i] < *min_exp_end_with_task)
  132. *min_exp_end_with_task = estimated_ends_with_task[i];
  133. if(estimated_ends_with_task[i] > *max_exp_end_with_task)
  134. *max_exp_end_with_task = estimated_ends_with_task[i];
  135. suitable_components[nsuitable_components++] = i;
  136. }
  137. }
  138. return nsuitable_components;
  139. }