From f7f97f7369be31efa83102c6718adb88ce2f9c01 Mon Sep 17 00:00:00 2001 From: SUTER Frederic Date: Tue, 4 May 2021 15:33:17 +0200 Subject: [PATCH] add Profile support for Disk --- include/simgrid/s4u/Disk.hpp | 4 ++ src/kernel/resource/DiskImpl.cpp | 53 +++++++++++++++---------- src/kernel/resource/DiskImpl.hpp | 28 +++++++------- src/s4u/s4u_Disk.cpp | 21 ++++++++++ src/surf/disk_s19.cpp | 66 ++++++++++++++++++++++++++++++++ src/surf/disk_s19.hpp | 3 ++ 6 files changed, 141 insertions(+), 34 deletions(-) diff --git a/include/simgrid/s4u/Disk.hpp b/include/simgrid/s4u/Disk.hpp index aac0f6b29a..5f395d667e 100644 --- a/include/simgrid/s4u/Disk.hpp +++ b/include/simgrid/s4u/Disk.hpp @@ -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; diff --git a/src/kernel/resource/DiskImpl.cpp b/src/kernel/resource/DiskImpl.cpp index 5ae459329e..cbc75c2383 100644 --- a/src/kernel/resource/DiskImpl.cpp +++ b/src/kernel/resource/DiskImpl.cpp @@ -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(); } diff --git a/src/kernel/resource/DiskImpl.hpp b/src/kernel/resource/DiskImpl.hpp index 7060d7d6f6..694972bc7d 100644 --- a/src/kernel/resource/DiskImpl.hpp +++ b/src/kernel/resource/DiskImpl.hpp @@ -47,21 +47,19 @@ public: * Resource * ************/ class DiskImpl : public Resource_T, 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 diff --git a/src/s4u/s4u_Disk.cpp b/src/s4u/s4u_Disk.cpp index fd3c30dd3d..735eeaeda0 100644 --- a/src/s4u/s4u_Disk.cpp +++ b/src/s4u/s4u_Disk.cpp @@ -85,6 +85,27 @@ Disk* Disk::set_properties(const std::unordered_map& 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); diff --git a/src/surf/disk_s19.cpp b/src/surf/disk_s19.cpp index e0e084a236..ede1c450c9 100644 --- a/src/surf/disk_s19.cpp +++ b/src/surf/disk_s19.cpp @@ -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(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(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 * **********/ diff --git a/src/surf/disk_s19.hpp b/src/surf/disk_s19.hpp index 35a043a7bc..7754757532 100644 --- a/src/surf/disk_s19.hpp +++ b/src/surf/disk_s19.hpp @@ -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); }; /********** -- 2.20.1