From: Fred Suter Date: Wed, 3 May 2023 14:39:56 +0000 (-0400) Subject: further simplify this example X-Git-Tag: v3.34~131^2~10 X-Git-Url: http://bilbo.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/commitdiff_plain/995a7675c8b86fd972d607f031c09136fe699f58?hp=de6f03f2a89a0e4810740ef55689e82cede38e31 further simplify this example --- diff --git a/examples/cpp/dag-scheduling/s4u-dag-scheduling.cpp b/examples/cpp/dag-scheduling/s4u-dag-scheduling.cpp index c61f83f877..5386b58002 100644 --- a/examples/cpp/dag-scheduling/s4u-dag-scheduling.cpp +++ b/examples/cpp/dag-scheduling/s4u-dag-scheduling.cpp @@ -37,57 +37,56 @@ static std::vector get_ready_tasks(const std::vectorget_dependencies()) { - /* normal case */ - if (const auto* comm = dynamic_cast(parent.get())) { - auto source = comm->get_source(); - XBT_DEBUG("transfer from %s to %s", source->get_cname(), host->get_cname()); - /* Estimate the redistribution time from this parent */ - double redist_time; - if (comm->get_remaining() <= 1e-6) { - redist_time = 0; - } else { - double bandwidth = std::numeric_limits::max(); - auto [links, latency] = source->route_to(host); - for (auto const& link : links) - bandwidth = std::min(bandwidth, link->get_bandwidth()); - - redist_time = latency + comm->get_remaining() / bandwidth; - } - // We use the user data field to store the finish time of the predecessor of the comm, i.e., its potential start - // time - data_available = *comm->get_data() + redist_time; - } - - /* no transfer, control dependency */ - if (const auto* exec = dynamic_cast(parent.get())) - data_available = exec->get_finish_time(); - - if (last_data_available < data_available) - last_data_available = data_available; - } - return std::max(*host->get_data(), last_data_available) + task->get_remaining() / host->get_speed(); -} - -static sg4::Host* get_best_host(const sg4::ExecPtr exec) +static sg4::Host* get_best_host(const sg4::ExecPtr exec, double* min_finish_time) { sg4::Host* best_host = nullptr; - double min_EFT = std::numeric_limits::max(); + *min_finish_time = std::numeric_limits::max(); for (const auto& host : sg4::Engine::get_instance()->get_all_hosts()) { - double EFT = finish_on_at(exec, host); - XBT_DEBUG("%s finishes on %s at %f", exec->get_cname(), host->get_cname(), EFT); + double data_available = 0.; + double last_data_available = -1.0; + /* compute last_data_available */ + for (const auto& parent : exec->get_dependencies()) { + /* normal case */ + if (const auto* comm = dynamic_cast(parent.get())) { + auto source = comm->get_source(); + XBT_DEBUG("transfer from %s to %s", source->get_cname(), host->get_cname()); + /* Estimate the redistribution time from this parent */ + double redist_time; + if (comm->get_remaining() <= 1e-6) { + redist_time = 0; + } else { + double bandwidth = std::numeric_limits::max(); + auto [links, latency] = source->route_to(host); + for (auto const& link : links) + bandwidth = std::min(bandwidth, link->get_bandwidth()); + + redist_time = latency + comm->get_remaining() / bandwidth; + } + // We use the user data field to store the finish time of the predecessor of the comm, i.e., its potential + // start time + data_available = *comm->get_data() + redist_time; + } + + /* no transfer, control dependency */ + if (const auto* exec = dynamic_cast(parent.get())) + data_available = exec->get_finish_time(); + + if (last_data_available < data_available) + last_data_available = data_available; + } - if (EFT < min_EFT) { - min_EFT = EFT; - best_host = host; + double finish_time = std::max(*host->get_data(), last_data_available) + + exec->get_remaining() / host->get_speed(); + + XBT_DEBUG("%s finishes on %s at %f", exec->get_cname(), host->get_cname(), finish_time); + + if (finish_time < *min_finish_time) { + *min_finish_time = finish_time; + best_host = host; } } + return best_host; } @@ -149,8 +148,9 @@ int main(int argc, char** argv) auto dax = sg4::create_DAG_from_DAX(argv[2]); /* Schedule the root first */ + double finish_time; auto* root = static_cast(dax.front().get()); - auto host = get_best_host(root); + auto host = get_best_host(root, &finish_time); schedule_on(root, host); e.run(); @@ -162,25 +162,25 @@ int main(int argc, char** argv) vetoed.clear(); if (ready_tasks.empty()) { - /* there is no ready task, let advance the simulation */ + /* there is no ready exec, let advance the simulation */ e.run(); continue; } - /* For each ready task: + /* For each ready exec: * get the host that minimizes the completion time. - * select the task that has the minimum completion time on its best host. + * select the exec that has the minimum completion time on its best host. */ - double min_finish_time = -1.0; - sg4::Exec* selected_task = nullptr; - sg4::Host* selected_host = nullptr; - - for (auto task : ready_tasks) { - XBT_DEBUG("%s is ready", task->get_cname()); - host = get_best_host(task); - double finish_time = finish_on_at(task, host); - if (min_finish_time < 0 || finish_time < min_finish_time) { + double min_finish_time = std::numeric_limits::max(); + sg4::Exec* selected_task = nullptr; + sg4::Host* selected_host = nullptr; + + for (auto exec : ready_tasks) { + XBT_DEBUG("%s is ready", exec->get_cname()); + double finish_time; + host = get_best_host(exec, &finish_time); + if (finish_time < min_finish_time) { min_finish_time = finish_time; - selected_task = task; + selected_task = exec; selected_host = host; } }