From 4ef35cbc32fca05bb1d2cb9f5855430aaddfea92 Mon Sep 17 00:00:00 2001 From: Loic Guegan Date: Wed, 1 Apr 2020 16:39:13 +0200 Subject: [PATCH] Add WIFI decay model along with tesh tests. --- examples/platforms/wifi_decay_2STA.xml | 36 ++++++++ src/surf/network_wifi.cpp | 34 +++++++- src/surf/network_wifi.hpp | 15 ++++ teshsuite/surf/CMakeLists.txt | 2 +- .../wifi_usage_decay/wifi_usage_decay.cpp | 86 +++++++++++++++++++ .../wifi_usage_decay/wifi_usage_decay.tesh | 47 ++++++++++ 6 files changed, 218 insertions(+), 2 deletions(-) create mode 100755 examples/platforms/wifi_decay_2STA.xml create mode 100644 teshsuite/surf/wifi_usage_decay/wifi_usage_decay.cpp create mode 100644 teshsuite/surf/wifi_usage_decay/wifi_usage_decay.tesh diff --git a/examples/platforms/wifi_decay_2STA.xml b/examples/platforms/wifi_decay_2STA.xml new file mode 100755 index 0000000000..fed5614afa --- /dev/null +++ b/examples/platforms/wifi_decay_2STA.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/surf/network_wifi.cpp b/src/surf/network_wifi.cpp index 7a0896ee61..29d1c5f330 100644 --- a/src/surf/network_wifi.cpp +++ b/src/surf/network_wifi.cpp @@ -32,6 +32,9 @@ void NetworkWifiLink::set_host_rate(const 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; + + // Each time we add a host, we refresh the decay model + refresh_decay_bandwidths(); } double NetworkWifiLink::get_host_rate(const s4u::Host* host) @@ -46,7 +49,7 @@ double NetworkWifiLink::get_host_rate(const s4u::Host* host) xbt_assert(rate_id >= 0 && rate_id < (int)bandwidths_.size(), "Host '%s' has an invalid rate '%d' on wifi link '%s'", host->get_name().c_str(), rate_id, this->get_cname()); - Metric rate = bandwidths_[rate_id]; + Metric rate = use_decay_model_ ? decay_bandwidths_[rate_id] : bandwidths_[rate_id]; return rate.peak * rate.scale; } @@ -55,6 +58,35 @@ s4u::Link::SharingPolicy NetworkWifiLink::get_sharing_policy() return s4u::Link::SharingPolicy::WIFI; } +void NetworkWifiLink::refresh_decay_bandwidths(){ + // Compute number of STAtion on the Access Point + int nSTA=host_rates_.size(); + + std::vector new_bandwidths; + for (auto bandwidth : bandwidths_){ + // Instanciate decay model relatively to the actual bandwidth + double max_bw=bandwidth.peak; + double min_bw=bandwidth.peak-(wifi_max_rate_-wifi_min_rate_); + double model_rate=bandwidth.peak-(wifi_max_rate_-model_rate_); + + xbt_assert(min_bw > 0, "Your WIFI link is using bandwidth(s) which is too low for the decay model."); + + double N0=max_bw-min_bw; + double lambda=(-log(model_rate-min_bw)+log(N0))/model_n_; + // Since decay model start at 0 we should use (nSTA-1) + double new_peak=N0*exp(-lambda*(nSTA-1))+min_bw; + new_bandwidths.push_back({new_peak, 1.0, nullptr}); + + } + decay_bandwidths_=new_bandwidths; +} + +bool NetworkWifiLink::toggle_decay_model(){ + use_decay_model_=!use_decay_model_; + return(use_decay_model_); +} + + } // namespace resource } // namespace kernel } // namespace simgrid diff --git a/src/surf/network_wifi.hpp b/src/surf/network_wifi.hpp index a7887c1dd6..ef07cb4d4f 100644 --- a/src/surf/network_wifi.hpp +++ b/src/surf/network_wifi.hpp @@ -26,6 +26,19 @@ class NetworkWifiLink : public LinkImpl { /** @brief A link can have several bandwith attach to it (mostly use by wifi model) */ std::vector bandwidths_; + /** @brief Should we use the decay model ? */ + bool use_decay_model_=false; + /** @brief Wifi ns-3 802.11n average bit rate */ + const double wifi_max_rate_=54*1e6 / 8; + /** @brief ns-3 802.11n minimum bit rate */ + const double wifi_min_rate_=41.70837*1e6 / 8; + /** @brief Decay model calibration */ + const int model_n_=5; + /** @brief Decay model calibration: bitrate when using model_n_ stations */ + const double model_rate_=42.61438*1e6 / 8; + /** @brief Decay model bandwidths */ + std::vector decay_bandwidths_; + public: NetworkWifiLink(NetworkCm02Model* model, const std::string& name, std::vector bandwidths, lmm::System* system); @@ -38,6 +51,8 @@ public: void apply_event(kernel::profile::Event*, double) override { THROW_UNIMPLEMENTED; } void set_bandwidth(double) override { THROW_UNIMPLEMENTED; } void set_latency(double) override { THROW_UNIMPLEMENTED; } + void refresh_decay_bandwidths(); + bool toggle_decay_model(); }; } // namespace resource diff --git a/teshsuite/surf/CMakeLists.txt b/teshsuite/surf/CMakeLists.txt index fcedf0de3a..fa59bb3536 100644 --- a/teshsuite/surf/CMakeLists.txt +++ b/teshsuite/surf/CMakeLists.txt @@ -1,4 +1,4 @@ -foreach(x lmm_usage surf_usage surf_usage2 wifi_usage) +foreach(x lmm_usage surf_usage surf_usage2 wifi_usage wifi_usage_decay) add_executable (${x} EXCLUDE_FROM_ALL ${x}/${x}.cpp) target_link_libraries(${x} simgrid) set_target_properties(${x} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${x}) diff --git a/teshsuite/surf/wifi_usage_decay/wifi_usage_decay.cpp b/teshsuite/surf/wifi_usage_decay/wifi_usage_decay.cpp new file mode 100644 index 0000000000..feabf0b8ab --- /dev/null +++ b/teshsuite/surf/wifi_usage_decay/wifi_usage_decay.cpp @@ -0,0 +1,86 @@ +/* Copyright (c) 2019-2020. The SimGrid Team. All rights reserved. */ + +/* 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 "simgrid/s4u.hpp" +#include "xbt/log.h" + +#include "simgrid/msg.h" +#include "src/surf/network_wifi.hpp" + +XBT_LOG_NEW_DEFAULT_CATEGORY(simulator, "[usage] wifi_usage "); + +void run_ping_test(const char* src, const char* dest, int data_size); + +/* We need a separate actor so that it can sleep after each test */ +static void main_dispatcher() +{ + bool crosstraffic = simgrid::kernel::resource::NetworkModel::cfg_crosstraffic; + + XBT_INFO("TEST: Send from a station to a node on the wired network after the AP."); + XBT_INFO("----------------------------------------------------------------------"); + XBT_INFO("Since AP1 is the limiting link, we have the following constraint for AP1:"); + if (crosstraffic) { + XBT_INFO("1.05/r_STA1 * rho_STA1 <= 1 (1.05 instead of 1 because of cross-traffic)"); + XBT_INFO("However, decay model specify that for 2 stations, we have 54Mbps become 49.00487"); + XBT_INFO("We should thus have:"); + XBT_INFO(" mu = 1 / [ 1/1 * 1.05/49.00487Mbps ] = 46671305"); + XBT_INFO(" simulation_time = 1000*8 / mu = 0.0001714115 (rounded to 0.000171s in SimGrid)"); + } else { + XBT_INFO("1/r_STA1 * rho_STA1 <= 1 (there is no cross-traffic)"); + XBT_INFO("However, decay model specify that for 2 stations, we have 54Mbps become 49.00487"); + XBT_INFO("We should thus have:"); + XBT_INFO(" mu = 1 / [ 1/1 * 1/49.00487Mbps ] = 49004870"); + XBT_INFO(" simulation_time = 1000*8 / mu = 0.0001632491s (rounded to 0.000163s in SimGrid)"); + } + run_ping_test("Station 1", "NODE1", 1000); + + XBT_INFO("TEST: Send from a station to another station on the same AP."); + XBT_INFO("------------------------------------------------------------"); + XBT_INFO("We have the following constraint for AP1:"); + if (crosstraffic) { + XBT_INFO("1.05/r_STA1 * rho_STA1 + 1.05/r_STA2 * rho_2 <= 1 (1.05 instead of 1 because of cross-traffic)"); + XBT_INFO("However, decay model specify that for 2 stations, we have 54Mbps become 49.00487"); + XBT_INFO("We should thus have:"); + XBT_INFO(" mu = 1 / [ 1/2 * 1.05/49.00487Mbps + 1.05/49.00487Mbps ] = 46671305"); + XBT_INFO(" simulation_time = 1000*8 / [ mu / 2 ] = 0.0003428231s (rounded to 0.000343s in SimGrid)"); + } else { + XBT_INFO("1/r_STA1 * rho_STA1 + 1/r_STA2 * rho_2 <= 1 (there is no cross-traffic)"); + XBT_INFO("However, decay model specify that for 2 stations, we have 54Mbps become 49.00487"); + XBT_INFO(" mu = 1 / [ 1/2 * 1/49.00487Mbps + 1/49.00487Mbps ] = 49004870"); + XBT_INFO(" simulation_time = 1000*8 / [ mu / 2 ] = 0.0003264982s (rounded to 0.000326s in SimGrid)"); + } + run_ping_test("Station 1", "Station 2", 1000); +} +int main(int argc, char** argv) +{ + simgrid::s4u::Engine engine(&argc, argv); + engine.load_platform(argv[1]); + simgrid::s4u::Actor::create("dispatcher", simgrid::s4u::Host::by_name("NODE1"), main_dispatcher); + engine.run(); + + return 0; +} + +void run_ping_test(const char* src, const char* dest, int data_size) +{ + auto* mailbox = simgrid::s4u::Mailbox::by_name("Test"); + + simgrid::s4u::Actor::create("sender", simgrid::s4u::Host::by_name(src), [mailbox, dest, data_size]() { + double start_time = simgrid::s4u::Engine::get_clock(); + static char message[] = "message"; + mailbox->put(message, data_size); + double end_time = simgrid::s4u::Engine::get_clock(); + XBT_INFO("Actual result: Sending %d bytes from '%s' to '%s' takes %f seconds.", data_size, + simgrid::s4u::this_actor::get_host()->get_cname(), dest, end_time - start_time); + }); + simgrid::s4u::Actor::create("receiver", simgrid::s4u::Host::by_name(dest), [mailbox]() { mailbox->get(); }); + auto* l = (simgrid::kernel::resource::NetworkWifiLink*)simgrid::s4u::Link::by_name("AP1")->get_impl(); + if(!l->toggle_decay_model()) + l->toggle_decay_model(); + l->set_host_rate(simgrid::s4u::Host::by_name("Station 1"), 0); + l->set_host_rate(simgrid::s4u::Host::by_name("Station 2"), 0); + simgrid::s4u::this_actor::sleep_for(10); + XBT_INFO("\n"); +} diff --git a/teshsuite/surf/wifi_usage_decay/wifi_usage_decay.tesh b/teshsuite/surf/wifi_usage_decay/wifi_usage_decay.tesh new file mode 100644 index 0000000000..810c9971fc --- /dev/null +++ b/teshsuite/surf/wifi_usage_decay/wifi_usage_decay.tesh @@ -0,0 +1,47 @@ +#!/usr/bin/env tesh + +p Test WITH crosstraffic +$ ${bindir:=.}/wifi_usage_decay ${platfdir}/wifi.xml --log=root.fmt=%m%n +> TEST: Send from a station to a node on the wired network after the AP. +> ---------------------------------------------------------------------- +> Since AP1 is the limiting link, we have the following constraint for AP1: +> 1.05/r_STA1 * rho_STA1 <= 1 (1.05 instead of 1 because of cross-traffic) +> However, decay model specify that for 2 stations, we have 54Mbps become 49.00487 +> We should thus have: +> mu = 1 / [ 1/1 * 1.05/49.00487Mbps ] = 46671305 +> simulation_time = 1000*8 / mu = 0.0001714115 (rounded to 0.000171s in SimGrid) +> Actual result: Sending 1000 bytes from 'Station 1' to 'NODE1' takes 0.000171 seconds. +> +> +> TEST: Send from a station to another station on the same AP. +> ------------------------------------------------------------ +> We have the following constraint for AP1: +> 1.05/r_STA1 * rho_STA1 + 1.05/r_STA2 * rho_2 <= 1 (1.05 instead of 1 because of cross-traffic) +> However, decay model specify that for 2 stations, we have 54Mbps become 49.00487 +> We should thus have: +> mu = 1 / [ 1/2 * 1.05/49.00487Mbps + 1.05/49.00487Mbps ] = 46671305 +> simulation_time = 1000*8 / [ mu / 2 ] = 0.0003428231s (rounded to 0.000343s in SimGrid) +> Actual result: Sending 1000 bytes from 'Station 1' to 'Station 2' takes 0.000343 seconds. + +p Test WITHOUT crosstraffic +$ ${bindir:=.}/wifi_usage_decay ${platfdir}/wifi.xml --log=root.fmt=%m%n --cfg=network/crosstraffic:0 +> Configuration change: Set 'network/crosstraffic' to '0' +> TEST: Send from a station to a node on the wired network after the AP. +> ---------------------------------------------------------------------- +> Since AP1 is the limiting link, we have the following constraint for AP1: +> 1/r_STA1 * rho_STA1 <= 1 (there is no cross-traffic) +> However, decay model specify that for 2 stations, we have 54Mbps become 49.00487 +> We should thus have: +> mu = 1 / [ 1/1 * 1/49.00487Mbps ] = 49004870 +> simulation_time = 1000*8 / mu = 0.0001632491s (rounded to 0.000163s in SimGrid) +> Actual result: Sending 1000 bytes from 'Station 1' to 'NODE1' takes 0.000163 seconds. +> +> +> TEST: Send from a station to another station on the same AP. +> ------------------------------------------------------------ +> We have the following constraint for AP1: +> 1/r_STA1 * rho_STA1 + 1/r_STA2 * rho_2 <= 1 (there is no cross-traffic) +> However, decay model specify that for 2 stations, we have 54Mbps become 49.00487 +> mu = 1 / [ 1/2 * 1/49.00487Mbps + 1/49.00487Mbps ] = 49004870 +> simulation_time = 1000*8 / [ mu / 2 ] = 0.0003264982s (rounded to 0.000326s in SimGrid) +> Actual result: Sending 1000 bytes from 'Station 1' to 'Station 2' takes 0.000326 seconds. \ No newline at end of file -- 2.20.1