Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
add Profile support for Disk
authorSUTER Frederic <frederic.suter@cc.in2p3.fr>
Tue, 4 May 2021 13:33:17 +0000 (15:33 +0200)
committerSUTER Frederic <frederic.suter@cc.in2p3.fr>
Tue, 4 May 2021 13:33:20 +0000 (15:33 +0200)
include/simgrid/s4u/Disk.hpp
src/kernel/resource/DiskImpl.cpp
src/kernel/resource/DiskImpl.hpp
src/s4u/s4u_Disk.cpp
src/surf/disk_s19.cpp
src/surf/disk_s19.hpp

index aac0f6b..5f395d6 100644 (file)
@@ -63,6 +63,10 @@ public:
   Disk* set_host(Host* host);
   Host* get_host() const;
 
+  Disk* set_state_profile(kernel::profile::Profile* profile);
+  Disk* set_read_bandwidth_profile(kernel::profile::Profile* profile);
+  Disk* set_write_bandwidth_profile(kernel::profile::Profile* profile);
+
   IoPtr io_init(sg_size_t size, s4u::Io::OpType type) const;
 
   IoPtr read_async(sg_size_t size) const;
index 5ae4593..cbc75c2 100644 (file)
@@ -8,6 +8,7 @@
 #include "simgrid/s4u/Engine.hpp"
 #include "src/kernel/EngineImpl.hpp"
 #include "src/kernel/lmm/maxmin.hpp"
+#include "src/kernel/resource/profile/Profile.hpp"
 
 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(res_disk, ker_resource, "Disk resources, that fuel I/O activities");
 
@@ -29,22 +30,19 @@ DiskModel::DiskModel(const std::string& name) : Model(name)
 /************
  * Resource *
  ************/
-DiskImpl* DiskImpl::set_host(s4u::Host* host)
-{
-  xbt_assert(host, "Cannot set host, none given");
-  host_ = host;
-  return this;
-}
-
-DiskImpl* DiskImpl::set_read_bandwidth(double read_bw)
+DiskImpl::DiskImpl(const std::string& name, double read_bandwidth, double write_bandwidth)
+    : Resource_T(name), piface_(this)
 {
-  read_bw_ = read_bw;
-  return this;
+  read_bw_.peak   = read_bandwidth;
+  read_bw_.scale  = 1.0;
+  write_bw_.peak  = write_bandwidth;
+  write_bw_.scale = 1.0;
 }
 
-DiskImpl* DiskImpl::set_write_bandwidth(double write_bw)
+DiskImpl* DiskImpl::set_host(s4u::Host* host)
 {
-  write_bw_ = write_bw;
+  xbt_assert(host, "Cannot set host, none given");
+  host_ = host;
   return this;
 }
 
@@ -75,11 +73,6 @@ bool DiskImpl::is_used() const
   return get_model()->get_maxmin_system()->constraint_used(get_constraint());
 }
 
-void DiskImpl::apply_event(kernel::profile::Event* /*event*/, double /*value*/)
-{
-  THROW_UNIMPLEMENTED;
-}
-
 void DiskImpl::turn_on()
 {
   if (not is_on()) {
@@ -95,14 +88,32 @@ void DiskImpl::turn_off()
   }
 }
 
+DiskImpl* DiskImpl::set_read_bandwidth_profile(profile::Profile* profile)
+{
+  if (profile) {
+    xbt_assert(read_bw_.event == nullptr, "Cannot set a second read bandwidth profile to Disk %s", get_cname());
+    read_bw_.event = profile->schedule(&profile::future_evt_set, this);
+  }
+  return this;
+}
+
+DiskImpl* DiskImpl::set_write_bandwidth_profile(profile::Profile* profile)
+{
+  if (profile) {
+    xbt_assert(write_bw_.event == nullptr, "Cannot set a second read bandwidth profile to Disk %s", get_cname());
+    write_bw_.event = profile->schedule(&profile::future_evt_set, this);
+  }
+  return this;
+}
+
 void DiskImpl::seal()
 {
   xbt_assert(this->get_model(), "Cannot seal Disk (%s) without setting the model first", get_cname());
   lmm::System* maxmin_system = get_model()->get_maxmin_system();
-  this->set_read_constraint(maxmin_system->constraint_new(this, read_bw_))
-      ->set_write_constraint(maxmin_system->constraint_new(this, write_bw_))
-      ->set_constraint(maxmin_system->constraint_new(this, std::max(read_bw_, write_bw_)));
-  XBT_DEBUG("Create resource with read_bw '%f' write_bw '%f'", read_bw_, write_bw_);
+  this->set_read_constraint(maxmin_system->constraint_new(this, read_bw_.peak * read_bw_.scale))
+      ->set_write_constraint(maxmin_system->constraint_new(this, write_bw_.peak * write_bw_.scale))
+      ->set_constraint(maxmin_system->constraint_new(this, std::max(read_bw_.peak, write_bw_.peak)));
+  XBT_DEBUG("Create resource with read_bw '%f' write_bw '%f'", read_bw_.peak, write_bw_.peak);
   Resource::seal();
   turn_on();
 }
index 7060d7d..694972b 100644 (file)
@@ -47,21 +47,19 @@ public:
  * Resource *
  ************/
 class DiskImpl : public Resource_T<DiskImpl>, public xbt::PropertyHolder {
-  s4u::Host* host_           = nullptr;
   s4u::Disk piface_;
-  double read_bw_ = -1.0;
-  double write_bw_ = 1.0;
+  s4u::Host* host_                   = nullptr;
   lmm::Constraint* constraint_write_ = nullptr; /* Constraint for maximum write bandwidth*/
-  lmm::Constraint* constraint_read_ = nullptr;  /* Constraint for maximum read bandwidth*/
+  lmm::Constraint* constraint_read_  = nullptr; /* Constraint for maximum read bandwidth*/
 
 protected:
   ~DiskImpl() override = default; // Disallow direct deletion. Call destroy() instead.
 
 public:
-  DiskImpl(const std::string& name, double read_bandwidth, double write_bandwidth)
-      : Resource_T(name), piface_(this), read_bw_(read_bandwidth), write_bw_(write_bandwidth)
-  {
-  }
+  Metric read_bw_  = {0.0, 0, nullptr};
+  Metric write_bw_ = {0.0, 0, nullptr};
+
+  explicit DiskImpl(const std::string& name, double read_bandwidth, double write_bandwidth);
   DiskImpl(const DiskImpl&) = delete;
   DiskImpl& operator=(const DiskImpl&) = delete;
 
@@ -71,11 +69,11 @@ public:
   DiskImpl* set_host(s4u::Host* host);
   s4u::Host* get_host() const { return host_; }
 
-  DiskImpl* set_read_bandwidth(double read_bw);
-  double get_read_bandwidth() const { return read_bw_; }
+  virtual void set_read_bandwidth(double read_bw) = 0;
+  double get_read_bandwidth() const { return read_bw_.peak * read_bw_.scale; }
 
-  DiskImpl* set_write_bandwidth(double write_bw);
-  double get_write_bandwidth() const { return write_bw_; }
+  virtual void set_write_bandwidth(double write_bw) = 0;
+  double get_write_bandwidth() const { return write_bw_.peak * write_bw_.scale; }
 
   DiskImpl* set_read_constraint(lmm::Constraint* constraint_read);
   lmm::Constraint* get_read_constraint() const { return constraint_read_; }
@@ -83,9 +81,11 @@ public:
   DiskImpl* set_write_constraint(lmm::Constraint* constraint_write);
   lmm::Constraint* get_write_constraint() const { return constraint_write_; }
 
+  DiskImpl* set_read_bandwidth_profile(profile::Profile* profile);
+  DiskImpl* set_write_bandwidth_profile(profile::Profile* profile);
+
   /** @brief Check if the Disk is used (if an action currently uses its resources) */
   bool is_used() const override;
-  void apply_event(profile::Event* event, double value) override;
   void turn_on() override;
   void turn_off() override;
 
@@ -103,6 +103,8 @@ public:
 
   using Action::Action;
   void set_state(simgrid::kernel::resource::Action::State state) override;
+
+  double sharing_penalty_ = {};
 };
 
 } // namespace resource
index fd3c30d..735eeae 100644 (file)
@@ -85,6 +85,27 @@ Disk* Disk::set_properties(const std::unordered_map<std::string, std::string>& p
   return this;
 }
 
+Disk* Disk::set_state_profile(kernel::profile::Profile* profile)
+{
+  xbt_assert(not pimpl_->is_sealed(), "Cannot set a state profile once the Disk is sealed");
+  kernel::actor::simcall([this, profile]() { this->pimpl_->set_state_profile(profile); });
+  return this;
+}
+
+Disk* Disk::set_read_bandwidth_profile(kernel::profile::Profile* profile)
+{
+  xbt_assert(not pimpl_->is_sealed(), "Cannot set a bandwidth profile once the Disk is sealed");
+  kernel::actor::simcall([this, profile]() { this->pimpl_->set_read_bandwidth_profile(profile); });
+  return this;
+}
+
+Disk* Disk::set_write_bandwidth_profile(kernel::profile::Profile* profile)
+{
+  xbt_assert(not pimpl_->is_sealed(), "Cannot set a bandwidth profile once the Disk is sealed");
+  kernel::actor::simcall([this, profile]() { this->pimpl_->set_write_bandwidth_profile(profile); });
+  return this;
+}
+
 IoPtr Disk::io_init(sg_size_t size, Io::OpType type) const
 {
   return Io::init()->set_disk(this)->set_size(size)->set_op_type(type);
index e0e084a..ede1c45 100644 (file)
@@ -10,6 +10,7 @@
 #include "simgrid/s4u/Host.hpp"
 #include "src/kernel/EngineImpl.hpp"
 #include "src/kernel/lmm/maxmin.hpp"
+#include "src/kernel/resource/profile/Event.hpp"
 #include "src/surf/xml/platf.hpp"
 #include "surf/surf.hpp"
 
@@ -70,6 +71,71 @@ DiskAction* DiskS19Model::io_start(const DiskImpl* disk, sg_size_t size, s4u::Io
 /************
  * Resource *
  ************/
+void DiskS19::set_read_bandwidth(double value)
+{
+  read_bw_.peak = value;
+
+  get_model()->get_maxmin_system()->update_constraint_bound(get_constraint(),
+                                                            sg_bandwidth_factor * (read_bw_.peak * read_bw_.scale));
+
+  double delta = 1.0 / value - 1.0 / (read_bw_.peak * read_bw_.scale);
+
+  const kernel::lmm::Element* elem     = nullptr;
+  const kernel::lmm::Element* nextelem = nullptr;
+  int numelem                          = 0;
+  while (const auto* var = get_constraint()->get_variable_safe(&elem, &nextelem, &numelem)) {
+    auto* action = static_cast<DiskS19Action*>(var->get_id());
+    action->sharing_penalty_ += delta;
+    if (not action->is_suspended())
+      get_model()->get_maxmin_system()->update_variable_penalty(action->get_variable(), action->sharing_penalty_);
+  }
+}
+
+void DiskS19::set_write_bandwidth(double value)
+{
+  write_bw_.peak = value;
+
+  get_model()->get_maxmin_system()->update_constraint_bound(get_constraint(),
+                                                            sg_bandwidth_factor * (write_bw_.peak * write_bw_.scale));
+
+  double delta = 1.0 / value - 1.0 / (write_bw_.peak * write_bw_.scale);
+
+  const kernel::lmm::Element* elem     = nullptr;
+  const kernel::lmm::Element* nextelem = nullptr;
+  int numelem                          = 0;
+  while (const auto* var = get_constraint()->get_variable_safe(&elem, &nextelem, &numelem)) {
+    auto* action = static_cast<DiskS19Action*>(var->get_id());
+    action->sharing_penalty_ += delta;
+    if (not action->is_suspended())
+      get_model()->get_maxmin_system()->update_variable_penalty(action->get_variable(), action->sharing_penalty_);
+  }
+}
+
+void DiskS19::apply_event(kernel::profile::Event* triggered, double value)
+{
+  /* Find out which of my iterators was triggered, and react accordingly */
+  if (triggered == read_bw_.event) {
+    set_read_bandwidth(value);
+    tmgr_trace_event_unref(&read_bw_.event);
+
+  } else if (triggered == write_bw_.event) {
+    set_write_bandwidth(value);
+    tmgr_trace_event_unref(&write_bw_.event);
+
+  } else if (triggered == state_event_) {
+    if (value > 0)
+      turn_on();
+    else
+      turn_off();
+    tmgr_trace_event_unref(&state_event_);
+  } else {
+    xbt_die("Unknown event!\n");
+  }
+
+  XBT_DEBUG("There was a resource state event, need to update actions related to the constraint (%p)",
+            get_constraint());
+}
+
 /**********
  * Action *
  **********/
index 35a043a..7754757 100644 (file)
@@ -43,6 +43,9 @@ public:
 class DiskS19 : public DiskImpl {
 public:
   using DiskImpl::DiskImpl;
+  void set_read_bandwidth(double value) override;
+  void set_write_bandwidth(double value) override;
+  void apply_event(kernel::profile::Event* triggered, double value);
 };
 
 /**********