X-Git-Url: http://bilbo.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/blobdiff_plain/f0534a5e2af72c36c12d55f7ea323040e6e9bf36..1363ce9624f4327f3ad5c934b15736a776637dfd:/src/mc/api/strategy/MinMatchComm.hpp diff --git a/src/mc/api/strategy/MinMatchComm.hpp b/src/mc/api/strategy/MinMatchComm.hpp index 50fe6929ef..607a0a04a3 100644 --- a/src/mc/api/strategy/MinMatchComm.hpp +++ b/src/mc/api/strategy/MinMatchComm.hpp @@ -13,13 +13,14 @@ namespace simgrid::mc { /** Wait MC guiding class that aims at maximizing the number of in-fly communication. * When possible, it will try not to match communications. */ class MinMatchComm : public Strategy { - - /** Stores for each mailbox what kind of transition is waiting on it. * Negative number means that much recv are waiting on that mailbox, while * a positiv number means that much send are waiting there. */ std::map mailbox_; - int value_of_state_ = 100000; // used to valuate the state. Corresponds to the number of in-fly communications + /** Used to valuate the state. Corresponds to a maximum minus the number of in-fly communications. + * Maximum should be set in order not to reach 0.*/ + int value_of_state_ = _sg_mc_max_depth; + // The two next values are used to save the operation we execute so the next strategy can update its field accordingly Transition::Type last_transition_; unsigned last_mailbox_ = 0; @@ -27,7 +28,7 @@ class MinMatchComm : public Strategy { public: void copy_from(const Strategy* strategy) override { - const MinMatchComm* cast_strategy = static_cast(strategy); + const MinMatchComm* cast_strategy = dynamic_cast(strategy); xbt_assert(cast_strategy != nullptr); for (auto& [id, val] : cast_strategy->mailbox_) mailbox_[id] = val; @@ -38,84 +39,58 @@ public: for (auto const& [_, val] : mailbox_) value_of_state_ -= std::abs(val); - if (value_of_state_ < 0) - value_of_state_ = 0; + xbt_assert(value_of_state_ > 0, "MinMatchComm value shouldn't reach 0"); } MinMatchComm() = default; ~MinMatchComm() override = default; - std::pair next_transition() const override + std::pair best_transition(bool must_be_todo) const override { - std::pair if_no_match = std::make_pair(-1, 0); + std::pair min_found = std::make_pair(-1, value_of_state_+2); for (auto const& [aid, actor] : actors_to_run_) { - if (not actor.is_todo() || not actor.is_enabled() || actor.is_done()) - continue; + if ((not actor.is_todo() && must_be_todo) || not actor.is_enabled() || actor.is_done()) + continue; + int aid_value = value_of_state_; const Transition* transition = actor.get_transition(actor.get_times_considered()).get(); - const CommRecvTransition* cast_recv = static_cast(transition); - if (cast_recv != nullptr and mailbox_.count(cast_recv->get_mailbox()) > 0 and - mailbox_.at(cast_recv->get_mailbox()) <= 0) - return std::make_pair(aid, value_of_state_ - 1); // This means we don't have waiting recv corresponding to this recv - - const CommSendTransition* cast_send = static_cast(transition); - if (cast_send != nullptr and mailbox_.count(cast_send->get_mailbox()) > 0 and - mailbox_.at(cast_send->get_mailbox()) >= 0) - return std::make_pair(aid, value_of_state_ - 1); // This means we don't have waiting recv corresponding to this send - - if (if_no_match.first == -1) - if_no_match = std::make_pair(aid, value_of_state_); + const CommRecvTransition* cast_recv = dynamic_cast(transition); + if (cast_recv != nullptr) { + if ((mailbox_.count(cast_recv->get_mailbox()) > 0 and + mailbox_.at(cast_recv->get_mailbox()) <= 0) or mailbox_.count(cast_recv->get_mailbox()) == 0) + aid_value--; // This means we don't have waiting recv corresponding to this recv + else + aid_value++; + } + const CommSendTransition* cast_send = dynamic_cast(transition); + if (cast_send != nullptr) { + if ((mailbox_.count(cast_send->get_mailbox()) > 0 and + mailbox_.at(cast_send->get_mailbox()) >= 0) or mailbox_.count(cast_send->get_mailbox()) == 0) + aid_value--; + else + aid_value++; + } + + if (aid_value < min_found.second) + min_found = std::make_pair(aid, aid_value); } - return if_no_match; + return min_found; } + void execute_next(aid_t aid, RemoteApp& app) override { const Transition* transition = actors_to_run_.at(aid).get_transition(actors_to_run_.at(aid).get_times_considered()).get(); last_transition_ = transition->type_; - const CommRecvTransition* cast_recv = static_cast(transition); + const CommRecvTransition* cast_recv = dynamic_cast(transition); if (cast_recv != nullptr) last_mailbox_ = cast_recv->get_mailbox(); - const CommSendTransition* cast_send = static_cast(transition); + const CommSendTransition* cast_send = dynamic_cast(transition); if (cast_send != nullptr) last_mailbox_ = cast_send->get_mailbox(); } - - void consider_best() override - { - for (auto& [aid, actor] : actors_to_run_) - if (actor.is_todo()) - return; - - for (auto& [aid, actor] : actors_to_run_) { - if (not actor.is_enabled() || actor.is_done()) - continue; - - const Transition* transition = actor.get_transition(actor.get_times_considered()).get(); - - const CommRecvTransition* cast_recv = static_cast(transition); - if (cast_recv != nullptr and mailbox_.count(cast_recv->get_mailbox()) > 0 and - mailbox_.at(cast_recv->get_mailbox()) <= 0) { - actor.mark_todo(); - return; - } - - const CommSendTransition* cast_send = static_cast(transition); - if (cast_send != nullptr and mailbox_.count(cast_send->get_mailbox()) > 0 and - mailbox_.at(cast_send->get_mailbox()) >= 0) { - actor.mark_todo(); - return; - } - } - for (auto& [_, actor] : actors_to_run_) { - if (actor.is_enabled() and not actor.is_done()) { - actor.mark_todo(); - return; - } - } - } }; } // namespace simgrid::mc