component_mct.c 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. /* StarPU --- Runtime system for heterogeneous multicore architectures.
  2. *
  3. * Copyright (C) 2013-2017 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 "sched_component.h"
  20. #include <starpu_perfmodel.h>
  21. #include "helper_mct.h"
  22. #include <float.h>
  23. #include <core/sched_policy.h>
  24. #include <core/task.h>
  25. static int mct_push_task(struct starpu_sched_component * component, struct starpu_task * task)
  26. {
  27. STARPU_ASSERT(component && task && starpu_sched_component_is_mct(component));
  28. struct _starpu_mct_data * d = component->data;
  29. struct starpu_sched_component * best_component = NULL;
  30. /* Estimated task duration for each child */
  31. double estimated_lengths[component->nchildren];
  32. /* Estimated transfer duration for each child */
  33. double estimated_transfer_length[component->nchildren];
  34. /* Estimated transfer+task termination for each child */
  35. double estimated_ends_with_task[component->nchildren];
  36. int i;
  37. for(i=0; i < component->nchildren; i++)
  38. {
  39. estimated_lengths[i] = 0.0;
  40. estimated_transfer_length[i] = 0.0;
  41. estimated_ends_with_task[i] = 0.0;
  42. }
  43. /* Minimum transfer+task termination on all children */
  44. double min_exp_end_with_task = DBL_MAX;
  45. /* Maximum transfer+task termination on all children */
  46. double max_exp_end_with_task = 0.0;
  47. int suitable_components[component->nchildren];
  48. int nsuitable_components = 0;
  49. nsuitable_components = starpu_mct_compute_execution_times(component, task,
  50. estimated_lengths, estimated_transfer_length, suitable_components);
  51. /* If no suitable components were found, it means that the perfmodel of
  52. * the task had been purged since it has been pushed on the mct component.
  53. * We should send a push_fail message to its parent so that it will
  54. * be able to reschedule the task properly. */
  55. if(nsuitable_components == 0)
  56. return 1;
  57. /* Entering critical section to make sure no two workers
  58. make scheduling decisions at the same time */
  59. STARPU_PTHREAD_MUTEX_LOCK(&d->scheduling_mutex);
  60. starpu_mct_compute_expected_times(component, task, estimated_lengths, estimated_transfer_length,
  61. estimated_ends_with_task, &min_exp_end_with_task, &max_exp_end_with_task, suitable_components, nsuitable_components);
  62. double best_fitness = DBL_MAX;
  63. int best_icomponent = -1;
  64. for(i = 0; i < nsuitable_components; i++)
  65. {
  66. int icomponent = suitable_components[i];
  67. #ifdef STARPU_DEVEL
  68. #warning FIXME: take energy consumption into account
  69. #endif
  70. double tmp = starpu_mct_compute_fitness(d,
  71. estimated_ends_with_task[icomponent],
  72. min_exp_end_with_task,
  73. max_exp_end_with_task,
  74. estimated_transfer_length[icomponent],
  75. 0.0);
  76. if(tmp < best_fitness)
  77. {
  78. best_fitness = tmp;
  79. best_icomponent = icomponent;
  80. }
  81. }
  82. /* If no best component is found, it means that the perfmodel of
  83. * the task had been purged since it has been pushed on the mct component.
  84. * We should send a push_fail message to its parent so that it will
  85. * be able to reschedule the task properly. */
  86. if(best_icomponent == -1) {
  87. STARPU_PTHREAD_MUTEX_UNLOCK(&d->scheduling_mutex);
  88. return 1;
  89. }
  90. best_component = component->children[best_icomponent];
  91. task->predicted = estimated_lengths[best_icomponent];
  92. task->predicted_transfer = estimated_transfer_length[best_icomponent];
  93. if(starpu_sched_component_is_worker(best_component))
  94. {
  95. best_component->can_pull(best_component);
  96. STARPU_PTHREAD_MUTEX_UNLOCK(&d->scheduling_mutex);
  97. return 1;
  98. }
  99. _STARPU_TASK_BREAK_ON(task, sched);
  100. int ret = starpu_sched_component_push_task(component, best_component, task);
  101. /* I can now exit the critical section: Pushing the task below ensures that its execution
  102. time will be taken into account for subsequent scheduling decisions */
  103. STARPU_PTHREAD_MUTEX_UNLOCK(&d->scheduling_mutex);
  104. return ret;
  105. }
  106. static void mct_component_deinit_data(struct starpu_sched_component * component)
  107. {
  108. STARPU_ASSERT(starpu_sched_component_is_mct(component));
  109. struct _starpu_mct_data * d = component->data;
  110. STARPU_PTHREAD_MUTEX_DESTROY(&d->scheduling_mutex);
  111. free(d);
  112. }
  113. int starpu_sched_component_is_mct(struct starpu_sched_component * component)
  114. {
  115. return component->push_task == mct_push_task;
  116. }
  117. struct starpu_sched_component * starpu_sched_component_mct_create(struct starpu_sched_tree *tree, struct starpu_sched_component_mct_data * params)
  118. {
  119. struct starpu_sched_component * component = starpu_sched_component_create(tree, "mct");
  120. struct _starpu_mct_data *data = starpu_mct_init_parameters(params);
  121. component->data = data;
  122. STARPU_PTHREAD_MUTEX_INIT(&data->scheduling_mutex, NULL);
  123. component->push_task = mct_push_task;
  124. component->deinit_data = mct_component_deinit_data;
  125. return component;
  126. }