X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/blobdiff_plain/2aadff70152b2c1953b5776045da0ad05b5ac44d..49bd5a514ec76a1535f114fa2859db0347bfe5e8:/src/surf/network_cm02.cpp diff --git a/src/surf/network_cm02.cpp b/src/surf/network_cm02.cpp index 2f78a0de72..40cce3eb82 100644 --- a/src/surf/network_cm02.cpp +++ b/src/surf/network_cm02.cpp @@ -3,15 +3,16 @@ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ -#include -#include - #include "network_cm02.hpp" #include "simgrid/s4u/Host.hpp" #include "simgrid/sg_config.hpp" +#include "src/kernel/resource/profile/Event.hpp" #include "src/surf/surf_interface.hpp" #include "surf/surf.hpp" +#include +#include + XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(surf_network); double sg_latency_factor = 1.0; /* default value; can be set by model or from command line */ @@ -65,59 +66,6 @@ void surf_network_model_init_CM02() surf_network_model = new simgrid::kernel::resource::NetworkCm02Model(); } -/***************************************************************************/ -/* The models from Steven H. Low */ -/***************************************************************************/ -/* @article{Low03, */ -/* author={Steven H. Low}, */ -/* title={A Duality Model of {TCP} and Queue Management Algorithms}, */ -/* year={2003}, */ -/* journal={{IEEE/ACM} Transactions on Networking}, */ -/* volume={11}, number={4}, */ -/* } */ -void surf_network_model_init_Reno() -{ - xbt_assert(surf_network_model == nullptr, "Cannot set the network model twice"); - - namespace lmm = simgrid::kernel::lmm; - lmm::Lagrange::set_default_protocol_function(lmm::func_reno_f, lmm::func_reno_fp, lmm::func_reno_fpi); - - simgrid::config::set_default("network/latency-factor", 13.01); - simgrid::config::set_default("network/bandwidth-factor", 0.97); - simgrid::config::set_default("network/weight-S", 20537); - - surf_network_model = new simgrid::kernel::resource::NetworkCm02Model(&simgrid::kernel::lmm::make_new_lagrange_system); -} - - -void surf_network_model_init_Reno2() -{ - xbt_assert(surf_network_model == nullptr, "Cannot set the network model twice"); - - namespace lmm = simgrid::kernel::lmm; - lmm::Lagrange::set_default_protocol_function(lmm::func_reno2_f, lmm::func_reno2_fp, lmm::func_reno2_fpi); - - simgrid::config::set_default("network/latency-factor", 13.01); - simgrid::config::set_default("network/bandwidth-factor", 0.97); - simgrid::config::set_default("network/weight-S", 20537); - - surf_network_model = new simgrid::kernel::resource::NetworkCm02Model(&simgrid::kernel::lmm::make_new_lagrange_system); -} - -void surf_network_model_init_Vegas() -{ - xbt_assert(surf_network_model == nullptr, "Cannot set the network model twice"); - - namespace lmm = simgrid::kernel::lmm; - lmm::Lagrange::set_default_protocol_function(lmm::func_vegas_f, lmm::func_vegas_fp, lmm::func_vegas_fpi); - - simgrid::config::set_default("network/latency-factor", 13.01); - simgrid::config::set_default("network/bandwidth-factor", 0.97); - simgrid::config::set_default("network/weight-S", 20537); - - surf_network_model = new simgrid::kernel::resource::NetworkCm02Model(&simgrid::kernel::lmm::make_new_lagrange_system); -} - namespace simgrid { namespace kernel { namespace resource { @@ -138,13 +86,18 @@ NetworkCm02Model::NetworkCm02Model(kernel::lmm::System* (*make_new_lmm_system)(b } set_maxmin_system(make_new_lmm_system(select)); - loopback_ = NetworkCm02Model::create_link("__loopback__", 498000000, 0.000015, s4u::Link::SharingPolicy::FATPIPE); + loopback_ = NetworkCm02Model::create_link("__loopback__", std::vector(1, 498000000), 0.000015, + s4u::Link::SharingPolicy::FATPIPE); } -LinkImpl* NetworkCm02Model::create_link(const std::string& name, double bandwidth, double latency, +LinkImpl* NetworkCm02Model::create_link(const std::string& name, const std::vector& bandwidths, double latency, s4u::Link::SharingPolicy policy) { - return new NetworkCm02Link(this, name, bandwidth, latency, policy, get_maxmin_system()); + if (policy == s4u::Link::SharingPolicy::WIFI) { + return (new NetworkWifiLink(this, name, bandwidths, policy, get_maxmin_system())); + } + xbt_assert(bandwidths.size() == 1, "Non WIFI links must use only 1 bandwidth."); + return new NetworkCm02Link(this, name, bandwidths[0], latency, policy, get_maxmin_system()); } void NetworkCm02Model::update_actions_state_lazy(double now, double /*delta*/) @@ -157,7 +110,7 @@ void NetworkCm02Model::update_actions_state_lazy(double now, double /*delta*/) // if I am wearing a latency hat if (action->get_type() == ActionHeap::Type::latency) { XBT_DEBUG("Latency paid for action %p. Activating", action); - get_maxmin_system()->update_variable_weight(action->get_variable(), action->weight_); + get_maxmin_system()->update_variable_penalty(action->get_variable(), action->sharing_penalty_); get_action_heap().remove(action); action->set_last_update(); @@ -188,7 +141,7 @@ void NetworkCm02Model::update_actions_state_full(double /*now*/, double delta) action.latency_ = 0.0; } if (action.latency_ <= 0.0 && not action.is_suspended()) - get_maxmin_system()->update_variable_weight(action.get_variable(), action.weight_); + get_maxmin_system()->update_variable_penalty(action.get_variable(), action.sharing_penalty_); } if (not action.get_variable()->get_number_of_constraint()) { @@ -202,7 +155,7 @@ void NetworkCm02Model::update_actions_state_full(double /*now*/, double delta) if (action.get_max_duration() != NO_MAX_DURATION) action.update_max_duration(delta); - if (((action.get_remains() <= 0) && (action.get_variable()->get_weight() > 0)) || + if (((action.get_remains() <= 0) && (action.get_variable()->get_penalty() > 0)) || ((action.get_max_duration() != NO_MAX_DURATION) && (action.get_max_duration() <= 0))) { action.finish(Action::State::FINISHED); } @@ -232,16 +185,17 @@ Action* NetworkCm02Model::communicate(s4u::Host* src, s4u::Host* dst, double siz } NetworkCm02Action *action = new NetworkCm02Action(this, size, failed); - action->weight_ = latency; + action->sharing_penalty_ = latency; action->latency_ = latency; action->rate_ = rate; + if (get_update_algorithm() == Model::UpdateAlgo::LAZY) { action->set_last_update(); } if (sg_weight_S_parameter > 0) { - action->weight_ = - std::accumulate(route.begin(), route.end(), action->weight_, [](double total, LinkImpl* const& link) { + action->sharing_penalty_ = + std::accumulate(route.begin(), route.end(), action->sharing_penalty_, [](double total, LinkImpl* const& link) { return total + sg_weight_S_parameter / link->get_bandwidth(); }); } @@ -282,8 +236,32 @@ Action* NetworkCm02Model::communicate(s4u::Host* src, s4u::Host* dst, double siz : action->rate_); } - for (auto const& link : route) - get_maxmin_system()->expand(link->get_constraint(), action->get_variable(), 1.0); + for (auto const& link : route) { + // Handle WIFI links + if (link->get_sharing_policy() == s4u::Link::SharingPolicy::WIFI) { + xbt_assert(!cfg_crosstraffic, + "Cross-traffic is not yet supported when using WIFI. Please use --cfg=network/crosstraffic:0"); + NetworkWifiLink* wifi_link = (NetworkWifiLink*)link; + + double src_rate = wifi_link->get_host_rate(src); + double dst_rate = wifi_link->get_host_rate(dst); + + // TODO: What do to when src and dst are on the same AP ? (for the moment we use src rate) + if (src_rate != -1 && dst_rate != -1) { + get_maxmin_system()->expand(link->get_constraint(), action->get_variable(), 1.0 / src_rate); + } else { + xbt_assert( + !(src_rate == -1 && dst_rate == -1), + "Some Stations are not associated to any Access Point. Make sure to call set_host_rate on all Stations."); + if (src_rate != -1) + get_maxmin_system()->expand(link->get_constraint(), action->get_variable(), 1.0 / src_rate); + else + get_maxmin_system()->expand(link->get_constraint(), action->get_variable(), 1.0 / dst_rate); + } + } else { + get_maxmin_system()->expand(link->get_constraint(), action->get_variable(), 1.0); + } + } if (cfg_crosstraffic) { XBT_DEBUG("Crosstraffic active: adding backward flow using 5%% of the available bandwidth"); @@ -296,7 +274,7 @@ Action* NetworkCm02Model::communicate(s4u::Host* src, s4u::Host* dst, double siz } XBT_OUT(); - simgrid::s4u::Link::on_communicate(action, src, dst); + simgrid::s4u::Link::on_communicate(*action, src, dst); return action; } @@ -334,19 +312,7 @@ void NetworkCm02Link::apply_event(kernel::profile::Event* triggered, double valu if (value > 0) turn_on(); else { - kernel::lmm::Variable* var = nullptr; - const kernel::lmm::Element* elem = nullptr; - double now = surf_get_clock(); - turn_off(); - while ((var = get_constraint()->get_variable(&elem))) { - Action* action = static_cast(var->get_id()); - - if (action->get_state() == Action::State::INITED || action->get_state() == Action::State::STARTED) { - action->set_finish_time(now); - action->set_state(Action::State::FAILED); - } - } } tmgr_trace_event_unref(&state_event_); } else { @@ -375,9 +341,9 @@ void NetworkCm02Link::set_bandwidth(double value) int numelem = 0; while ((var = get_constraint()->get_variable_safe(&elem, &nextelem, &numelem))) { NetworkCm02Action* action = static_cast(var->get_id()); - action->weight_ += delta; + action->sharing_penalty_ += delta; if (not action->is_suspended()) - get_model()->get_maxmin_system()->update_variable_weight(action->get_variable(), action->weight_); + get_model()->get_maxmin_system()->update_variable_penalty(action->get_variable(), action->sharing_penalty_); } } } @@ -395,7 +361,7 @@ void NetworkCm02Link::set_latency(double value) while ((var = get_constraint()->get_variable_safe(&elem, &nextelem, &numelem))) { NetworkCm02Action* action = static_cast(var->get_id()); action->lat_current_ += delta; - action->weight_ += delta; + action->sharing_penalty_ += delta; if (action->rate_ < 0) get_model()->get_maxmin_system()->update_variable_bound(action->get_variable(), NetworkModel::cfg_tcp_gamma / (2.0 * action->lat_current_)); @@ -410,20 +376,59 @@ void NetworkCm02Link::set_latency(double value) } } if (not action->is_suspended()) - get_model()->get_maxmin_system()->update_variable_weight(action->get_variable(), action->weight_); + get_model()->get_maxmin_system()->update_variable_penalty(action->get_variable(), action->sharing_penalty_); } } +NetworkWifiLink::NetworkWifiLink(NetworkCm02Model* model, const std::string& name, std::vector bandwidths, + s4u::Link::SharingPolicy policy, lmm::System* system) + : NetworkCm02Link( + model, name, 1 / sg_bandwidth_factor, 0, policy, + system) // Since link use bw*sg_bandwidth_factor we should divise in order to as 1 as bound in the lmm system +{ + for (auto bandwidth : bandwidths) { + bandwidths_.push_back({bandwidth, 1.0, nullptr}); + } +} + +void NetworkWifiLink::set_host_rate(s4u::Host* host, int rate_level) +{ + auto insert_done = host_rates_.insert(std::make_pair(host->get_name(), rate_level)); + if (insert_done.second == false) + insert_done.first->second = rate_level; +} + +double NetworkWifiLink::get_host_rate(sg_host_t host) +{ + std::map::iterator host_rates_it; + host_rates_it = host_rates_.find(host->get_name()); + + if (host_rates_it == host_rates_.end()) + return -1; + + int rate_id = host_rates_it->second; + xbt_assert(rate_id >= 0 && rate_id < (int)bandwidths_.size(), "Host \"%s\" has an invalid rate \"%d\"", + host->get_name().c_str(), rate_id); + + Metric rate = bandwidths_[rate_id]; + return rate.peak * rate.scale; +} + +s4u::Link::SharingPolicy NetworkWifiLink::get_sharing_policy() +{ + return s4u::Link::SharingPolicy::WIFI; +} + /********** * Action * **********/ void NetworkCm02Action::update_remains_lazy(double now) { - if (suspended_ != Action::SuspendStates::not_suspended) + if (not is_running()) return; - double delta = now - get_last_update(); + double delta = now - get_last_update(); if (get_remains_no_update() > 0) { XBT_DEBUG("Updating action(%p): remains was %f, last_update was: %f", this, get_remains_no_update(), @@ -435,7 +440,7 @@ void NetworkCm02Action::update_remains_lazy(double now) update_max_duration(delta); - if ((get_remains_no_update() <= 0 && (get_variable()->get_weight() > 0)) || + if ((get_remains_no_update() <= 0 && (get_variable()->get_penalty() > 0)) || ((get_max_duration() != NO_MAX_DURATION) && (get_max_duration() <= 0))) { finish(Action::State::FINISHED); get_model()->get_action_heap().remove(this);