From 46e8495798b154bcd1877f866b67f2c1d0ee1d6d Mon Sep 17 00:00:00 2001 From: Bruno Donassolo Date: Thu, 27 May 2021 16:57:57 +0200 Subject: [PATCH] New implementation for bandwidth factors Bandwidth factors are now implemented at the Action level, reducing the speed that an action advances (e.g. the number of bytes transmitted). In the past, the factor took place at the maxmin system, limiting the amount of resources a communication could use. For example, a bw factor of 0.97 (default for LV08 network model) was reflected by reducing the link capacity to 0.97*C. So, a 100MBs link had 97MBs capacity in the maxmin system. Now, a communication alone using this link may use the 100MBs, but after one second, it'll transmit only 97MB of data. NOTE: This change may impact the timing of your experiments. --- include/simgrid/kernel/resource/Action.hpp | 18 ++++++++++++++++++ src/instr/instr_platform.cpp | 2 +- src/kernel/resource/Action.cpp | 5 +++++ src/kernel/resource/Model.cpp | 4 ++-- src/plugins/link_energy_wifi.cpp | 11 +++++------ src/plugins/vm/VirtualMachineImpl.cpp | 2 +- src/surf/cpu_interface.cpp | 4 ++-- src/surf/disk_s19.cpp | 2 +- src/surf/network_cm02.cpp | 18 +++++++++++------- src/surf/ptask_L07.cpp | 5 ++--- 10 files changed, 48 insertions(+), 23 deletions(-) diff --git a/include/simgrid/kernel/resource/Action.hpp b/include/simgrid/kernel/resource/Action.hpp index fb24935660..aac2b9e024 100644 --- a/include/simgrid/kernel/resource/Action.hpp +++ b/include/simgrid/kernel/resource/Action.hpp @@ -72,6 +72,7 @@ class XBT_PUBLIC Action { activity::ActivityImpl* activity_ = nullptr; /* LMM */ + double factor_ = 1.0; /**< Factor for effective rate = var->get_value() * factor_ */ double last_update_ = 0; double last_value_ = 0; lmm::Variable* variable_ = nullptr; @@ -244,6 +245,23 @@ public: double get_last_update() const { return last_update_; } void set_last_update(); + /** + * @brief Set a factor for this action + * + * Defines a multiplicative factor for the consumption of the underlying resource. + * + * @param factor Multiplicative factor for this action (e.g. 0.97) + */ + void set_rate_factor(double factor) { factor_ = factor; } + /** + * @brief Get the effective consumption rate of the resource + * + * The rate is based on the sharing given by the maxmin system underneath. + * However, it depends on the factor defined for this action. + * + * So, the effective rate is equal to var->get_value() * factor_ + */ + double get_rate() const; double get_last_value() const { return last_value_; } void set_last_value(double val) { last_value_ = val; } void set_suspend_state(Action::SuspendStates state) { suspended_ = state; } diff --git a/src/instr/instr_platform.cpp b/src/instr/instr_platform.cpp index 08b0fb1c79..6db1c3bbad 100644 --- a/src/instr/instr_platform.cpp +++ b/src/instr/instr_platform.cpp @@ -336,7 +336,7 @@ static void on_action_state_change(kernel::resource::Action const& action, auto n = static_cast(action.get_variable()->get_number_of_constraint()); for (unsigned i = 0; i < n; i++) { - double value = action.get_variable()->get_value() * action.get_variable()->get_constraint_weight(i); + double value = action.get_rate() * action.get_variable()->get_constraint_weight(i); /* Beware of composite actions: ptasks put links and cpus together. Extra pb: we cannot dynamic_cast from void* */ kernel::resource::Resource* resource = action.get_variable()->get_constraint(i)->get_id(); const kernel::resource::CpuImpl* cpu = dynamic_cast(resource); diff --git a/src/kernel/resource/Action.cpp b/src/kernel/resource/Action.cpp index 338a5ab61e..825578bb99 100644 --- a/src/kernel/resource/Action.cpp +++ b/src/kernel/resource/Action.cpp @@ -96,6 +96,11 @@ double Action::get_bound() const return variable_ ? variable_->get_bound() : 0; } +double Action::get_rate() const +{ + return variable_ ? variable_->get_value() * factor_ : 0; +} + void Action::set_bound(double bound) { XBT_IN("(%p,%g)", this, bound); diff --git a/src/kernel/resource/Model.cpp b/src/kernel/resource/Model.cpp index b37c3b8112..905ac2dcef 100644 --- a/src/kernel/resource/Model.cpp +++ b/src/kernel/resource/Model.cpp @@ -68,7 +68,7 @@ double Model::next_occurring_event_lazy(double now) action->update_remains_lazy(now); double min = -1; - double share = action->get_variable()->get_value(); + double share = action->get_rate(); if (share > 0) { double time_to_completion; @@ -117,7 +117,7 @@ double Model::next_occurring_event_full(double /*now*/) double min = -1; for (Action& action : *get_started_action_set()) { - double value = action.get_variable()->get_value(); + double value = action.get_rate(); if (value > 0) { if (action.get_remains() > 0) value = action.get_remains_no_update() / value; diff --git a/src/plugins/link_energy_wifi.cpp b/src/plugins/link_energy_wifi.cpp index 8a227c3b21..f9332d1d1a 100644 --- a/src/plugins/link_energy_wifi.cpp +++ b/src/plugins/link_energy_wifi.cpp @@ -143,11 +143,10 @@ void LinkEnergyWifi::update(const kernel::resource::NetworkAction&) double durUsage = 0; while (const auto* var = wifi_link->get_constraint()->get_variable(&elem)) { auto* action = static_cast(var->get_id()); - XBT_DEBUG("cost: %f action value: %f link rate 1: %f link rate 2: %f", action->get_cost(), - action->get_variable()->get_value(), wifi_link->get_host_rate(&action->get_src()), - wifi_link->get_host_rate(&action->get_dst())); + XBT_DEBUG("cost: %f action value: %f link rate 1: %f link rate 2: %f", action->get_cost(), action->get_rate(), + wifi_link->get_host_rate(&action->get_src()), wifi_link->get_host_rate(&action->get_dst())); - if (action->get_variable()->get_value() != 0.0) { + if (action->get_rate() != 0.0) { auto it = flowTmp.find(action); // if the flow has not been registered, initialize it: 0 bytes sent, and not updated since its creation timestamp @@ -161,7 +160,7 @@ void LinkEnergyWifi::update(const kernel::resource::NetworkAction&) * If this is longer than the duration since the previous update, active duration = now - previous_update */ double du = // durUsage on the current flow - (action->get_cost() - it->second.first) / action->get_variable()->get_value(); + (action->get_cost() - it->second.first) / action->get_rate(); if(du > surf_get_clock()-it->second.second) du = surf_get_clock()-it->second.second; @@ -171,7 +170,7 @@ void LinkEnergyWifi::update(const kernel::resource::NetworkAction&) durUsage = du; // update the amount of data already sent by the flow - it->second.first += du*action->get_variable()->get_value(); + it->second.first += du * action->get_rate(); it->second.second = surf_get_clock(); // important: if the transmission finished, remove it (needed for performance and multi-message flows) diff --git a/src/plugins/vm/VirtualMachineImpl.cpp b/src/plugins/vm/VirtualMachineImpl.cpp index 08ea671b0e..61e2e33f00 100644 --- a/src/plugins/vm/VirtualMachineImpl.cpp +++ b/src/plugins/vm/VirtualMachineImpl.cpp @@ -159,7 +159,7 @@ double VMModel::next_occurring_event(double now) const kernel::resource::CpuImpl* cpu = ws_vm->pimpl_cpu; // solved_value below is X1 in comment above: what this VM got in the sharing on the PM - double solved_value = ws_vm->get_vm_impl()->get_action()->get_variable()->get_value(); + double solved_value = ws_vm->get_vm_impl()->get_action()->get_rate(); XBT_DEBUG("assign %f to vm %s @ pm %s", solved_value, ws_vm->get_cname(), ws_vm->get_pm()->get_cname()); kernel::lmm::System* vcpu_system = cpu->get_model()->get_maxmin_system(); diff --git a/src/surf/cpu_interface.cpp b/src/surf/cpu_interface.cpp index bfa0af4c5c..24f37a891c 100644 --- a/src/surf/cpu_interface.cpp +++ b/src/surf/cpu_interface.cpp @@ -36,7 +36,7 @@ void CpuModel::update_actions_state_full(double /*now*/, double delta) auto& action = static_cast(*it); ++it; // increment iterator here since the following calls to action.finish() may invalidate it - action.update_remains(action.get_variable()->get_value() * delta); + action.update_remains(action.get_rate() * delta); action.update_max_duration(delta); if (((action.get_remains_no_update() <= 0) && (action.get_variable()->get_penalty() > 0)) || @@ -159,7 +159,7 @@ void CpuAction::update_remains_lazy(double now) } set_last_update(); - set_last_value(get_variable()->get_value()); + set_last_value(get_rate()); } xbt::signal CpuAction::on_state_change; diff --git a/src/surf/disk_s19.cpp b/src/surf/disk_s19.cpp index 22d9dbdfc1..aa2d0ec9c3 100644 --- a/src/surf/disk_s19.cpp +++ b/src/surf/disk_s19.cpp @@ -41,7 +41,7 @@ void DiskS19Model::update_actions_state(double /*now*/, double delta) for (auto it = std::begin(*get_started_action_set()); it != std::end(*get_started_action_set());) { auto& action = *it; ++it; // increment iterator here since the following calls to action.finish() may invalidate it - action.update_remains(rint(action.get_variable()->get_value() * delta)); + action.update_remains(rint(action.get_rate() * delta)); action.update_max_duration(delta); if (((action.get_remains_no_update() <= 0) && (action.get_variable()->get_penalty() > 0)) || diff --git a/src/surf/network_cm02.cpp b/src/surf/network_cm02.cpp index 8e1c76df95..a11156a8e1 100644 --- a/src/surf/network_cm02.cpp +++ b/src/surf/network_cm02.cpp @@ -187,7 +187,7 @@ void NetworkCm02Model::update_actions_state_full(double /*now*/, double delta) */ action.update_remains(action.get_remains()); } - action.update_remains(action.get_variable()->get_value() * delta); + action.update_remains(action.get_rate() * delta); if (action.get_max_duration() != NO_MAX_DURATION) action.update_max_duration(delta); @@ -338,6 +338,10 @@ void NetworkCm02Model::comm_action_set_bounds(const s4u::Host* src, const s4u::H } else { bw_factor = get_bandwidth_factor(size); } + xbt_assert(bw_factor != 0, "Invalid param for comm %s -> %s. Bandwidth factor cannot be 0", src->get_cname(), + dst->get_cname()); + action->set_rate_factor(bw_factor); + /* get mininum bandwidth among links in the route and multiply by correct factor * ignore wi-fi links, they're not considered for bw_factors */ double bandwidth_bound = -1.0; @@ -347,12 +351,13 @@ void NetworkCm02Model::comm_action_set_bounds(const s4u::Host* src, const s4u::H if (bandwidth_bound == -1.0 || l->get_bandwidth() < bandwidth_bound) bandwidth_bound = l->get_bandwidth(); } - bandwidth_bound *= bw_factor; + /* increase rate given by user considering the factor, since the actual rate will be + * modified by it */ + rate = rate / bw_factor; /* the bandwidth is determined by the minimum between flow and user's defined rate */ if (rate >= 0 && rate < bandwidth_bound) bandwidth_bound = rate; - action->set_user_bound(bandwidth_bound); action->lat_current_ = action->latency_; @@ -439,7 +444,7 @@ NetworkCm02Link::NetworkCm02Link(const std::string& name, double bandwidth, kern { bandwidth_.scale = 1.0; bandwidth_.peak = bandwidth; - this->set_constraint(system->constraint_new(this, sg_bandwidth_factor * bandwidth)); + this->set_constraint(system->constraint_new(this, bandwidth)); } void NetworkCm02Link::apply_event(kernel::profile::Event* triggered, double value) @@ -471,8 +476,7 @@ void NetworkCm02Link::set_bandwidth(double value) { bandwidth_.peak = value; - get_model()->get_maxmin_system()->update_constraint_bound(get_constraint(), - sg_bandwidth_factor * (bandwidth_.peak * bandwidth_.scale)); + get_model()->get_maxmin_system()->update_constraint_bound(get_constraint(), (bandwidth_.peak * bandwidth_.scale)); LinkImpl::on_bandwidth_change(); @@ -555,7 +559,7 @@ void NetworkCm02Action::update_remains_lazy(double now) } set_last_update(); - set_last_value(get_variable()->get_value()); + set_last_value(get_rate()); } } // namespace resource diff --git a/src/surf/ptask_L07.cpp b/src/surf/ptask_L07.cpp index e6e51fcdbb..30a4f9e384 100644 --- a/src/surf/ptask_L07.cpp +++ b/src/surf/ptask_L07.cpp @@ -105,9 +105,8 @@ void HostL07Model::update_actions_state(double /*now*/, double delta) action.set_last_update(); } } - XBT_DEBUG("Action (%p) : remains (%g) updated by %g.", &action, action.get_remains(), - action.get_variable()->get_value() * delta); - action.update_remains(action.get_variable()->get_value() * delta); + XBT_DEBUG("Action (%p) : remains (%g) updated by %g.", &action, action.get_remains(), action.get_rate() * delta); + action.update_remains(action.get_rate() * delta); action.update_max_duration(delta); XBT_DEBUG("Action (%p) : remains (%g).", &action, action.get_remains()); -- 2.20.1