From 555ebc2e544437445450239b48e7df9b4f371460 Mon Sep 17 00:00:00 2001 From: Bruno Donassolo Date: Tue, 27 Jul 2021 10:23:30 +0200 Subject: [PATCH] I/O factors: noise for disks. Implements variability in disk operations. Similarly to network factors, the effective amount of bytes read/written in disk operations is scaled by a factor defined by the user. Users can define a different callback for each disk. The callback is called when SimGrid updates the remaining amount of bytes in disk operations. --- include/simgrid/s4u/Disk.hpp | 12 ++++++++++++ src/kernel/activity/IoImpl.cpp | 4 ++++ src/kernel/resource/DiskImpl.cpp | 6 ++++++ src/kernel/resource/DiskImpl.hpp | 4 ++++ src/s4u/s4u_Disk.cpp | 6 ++++++ 5 files changed, 32 insertions(+) diff --git a/include/simgrid/s4u/Disk.hpp b/include/simgrid/s4u/Disk.hpp index fcd8a651ab..5ba6306774 100644 --- a/include/simgrid/s4u/Disk.hpp +++ b/include/simgrid/s4u/Disk.hpp @@ -96,6 +96,18 @@ public: */ Disk* set_sharing_policy(Operation op, SharingPolicy policy, const s4u::NonLinearResourceCb& cb = {}); SharingPolicy get_sharing_policy(Operation op) const; + /** + * @brief Callback to set IO factors + * + * This callback offers a flexible way to create variability in I/O operations + * + * @param size I/O operation size in bytes + * @param op I/O operation type: read or write + * @return Multiply factor + */ + using IoFactorCb = double(sg_size_t size, Io::OpType op); + /** @brief Configure the factor callback */ + Disk* set_factor_cb(const std::function& cb); Disk* seal(); diff --git a/src/kernel/activity/IoImpl.cpp b/src/kernel/activity/IoImpl.cpp index 4f692b2990..bdef78f4d7 100644 --- a/src/kernel/activity/IoImpl.cpp +++ b/src/kernel/activity/IoImpl.cpp @@ -59,6 +59,10 @@ IoImpl* IoImpl::start() surf_action_ = disk_->get_host()->get_netpoint()->get_englobing_zone()->get_disk_model()->io_start(disk_, size_, type_); surf_action_->set_activity(this); + const auto& factor_cb = disk_->get_factor_cb(); + if (factor_cb) { // handling disk variability + surf_action_->set_rate_factor(factor_cb(size_, type_)); + } XBT_DEBUG("Create IO synchro %p %s", this, get_cname()); diff --git a/src/kernel/resource/DiskImpl.cpp b/src/kernel/resource/DiskImpl.cpp index dc0944946f..7b1fca1b4c 100644 --- a/src/kernel/resource/DiskImpl.cpp +++ b/src/kernel/resource/DiskImpl.cpp @@ -156,6 +156,12 @@ void DiskImpl::apply_sharing_policy_cfg() sharing_policy_cb_[s4u::Disk::Operation::WRITE]); } +void DiskImpl::set_factor_cb(const std::function& cb) +{ + xbt_assert(not is_sealed(), "Cannot set I/O factor callback in an already sealed disk(%s)", get_cname()); + factor_cb_ = cb; +} + /********** * Action * **********/ diff --git a/src/kernel/resource/DiskImpl.hpp b/src/kernel/resource/DiskImpl.hpp index c7835b6fc9..80905f909e 100644 --- a/src/kernel/resource/DiskImpl.hpp +++ b/src/kernel/resource/DiskImpl.hpp @@ -56,6 +56,7 @@ class DiskImpl : public Resource_T, public xbt::PropertyHolder { {s4u::Disk::Operation::WRITE, s4u::Disk::SharingPolicy::LINEAR}, {s4u::Disk::Operation::READWRITE, s4u::Disk::SharingPolicy::LINEAR}}; std::unordered_map sharing_policy_cb_ = {}; + std::function factor_cb_ = {}; void apply_sharing_policy_cfg(); @@ -94,6 +95,9 @@ public: void set_sharing_policy(s4u::Disk::Operation op, s4u::Disk::SharingPolicy policy, const s4u::NonLinearResourceCb& cb); s4u::Disk::SharingPolicy get_sharing_policy(s4u::Disk::Operation op) const; + void set_factor_cb(const std::function& cb); + const std::function& get_factor_cb() const { return factor_cb_; } + /** @brief Check if the Disk is used (if an action currently uses its resources) */ bool is_used() const override; void turn_on() override; diff --git a/src/s4u/s4u_Disk.cpp b/src/s4u/s4u_Disk.cpp index 29adfd31d4..d3f3a46100 100644 --- a/src/s4u/s4u_Disk.cpp +++ b/src/s4u/s4u_Disk.cpp @@ -142,6 +142,12 @@ Disk::SharingPolicy Disk::get_sharing_policy(Operation op) const return this->pimpl_->get_sharing_policy(op); } +Disk* Disk::set_factor_cb(const std::function& cb) +{ + kernel::actor::simcall([this, &cb] { pimpl_->set_factor_cb(cb); }); + return this; +} + Disk* Disk::seal() { kernel::actor::simcall([this]{ pimpl_->seal(); }); -- 2.20.1