1 /* Copyright (c) 2017-2022. The SimGrid Team. All rights reserved. */
3 /* This program is free software; you can redistribute it and/or modify it
4 * under the terms of the license (GNU LGPL) which comes with this package. */
6 /* This example shows how to simulate a non-linear resource sharing for disk
9 * It is inspired on the paper
10 * "Adding Storage Simulation Capacities to the SimGridToolkit: Concepts, Models, and API"
11 * Available at : https://hal.inria.fr/hal-01197128/document
13 * It shows how to simulate concurrent operations degrading overall performance of IO
14 * operations (specifically the effects presented in Fig. 8 of the paper).
17 #include <simgrid/s4u.hpp>
19 XBT_LOG_NEW_DEFAULT_CATEGORY(disk_test, "Messages specific for this simulation");
20 namespace sg4 = simgrid::s4u;
22 /** @brief Calculates the bandwidth for disk doing async operations */
23 static void estimate_bw(const sg4::Disk* disk, int n_flows, bool read)
25 unsigned long long size = 100000;
26 double cur_time = sg4::Engine::get_clock();
27 std::vector<sg4::IoPtr> activities;
28 for (int i = 0; i < n_flows; i++) {
31 act = disk->read_async(size);
33 act = disk->write_async(size);
35 activities.push_back(act);
38 for (const auto& act : activities)
41 double elapsed_time = sg4::Engine::get_clock() - cur_time;
42 double estimated_bw = static_cast<double>(size * n_flows) / elapsed_time;
43 XBT_INFO("Disk: %s, concurrent %s: %d, estimated bandwidth: %lf", disk->get_cname(), read ? "read" : "write", n_flows,
49 /* - Estimating bw for each disk and considering concurrent flows */
50 for (int n = 1; n < 15; n += 2) {
51 for (const auto* disk : sg4::Host::current()->get_disks()) {
52 estimate_bw(disk, n, true);
53 estimate_bw(disk, n, false);
59 * @brief Non-linear resource callback for SSD disks
61 * In this case, we have measurements for some resource sharing and directly use them to return the
63 * @param disk Disk on which the operation is happening (defined by the user through the std::bind)
64 * @param op read or write operation (defined by the user through the std::bind)
65 * @param capacity Resource current capacity in SimGrid
66 * @param n Number of activities sharing this resource
68 static double ssd_dynamic_sharing(const sg4::Disk* /*disk*/, const std::string& op, double capacity, int n)
70 /* measurements for SSD disks */
71 using DiskCapacity = std::unordered_map<int, double>;
72 static const std::unordered_map<std::string, DiskCapacity> SSD_SPEED = {{"write", {{1, 131.}}},
90 const auto& data = SSD_SPEED.at(op);
91 /* no special bandwidth for this disk sharing N flows, just returns maximal capacity */
92 if (data.find(n) != data.end())
93 capacity = data.at(n);
99 * @brief Non-linear resource callback for SATA disks
101 * In this case, the degradation for read operations is linear and we have a formula that represents it.
103 * @param disk Disk on which the operation is happening (defined by the user through the std::bind)
104 * @param capacity Resource current capacity in SimGrid
105 * @param n Number of activities sharing this resource
107 static double sata_dynamic_sharing(const sg4::Disk* /*disk*/, double /*capacity*/, int n)
109 return 68.3 - 1.7 * n;
112 /** @brief Creates an SSD disk, setting the appropriate callback for non-linear resource sharing */
113 static void create_ssd_disk(sg4::Host* host, const std::string& disk_name)
115 auto* disk = host->create_disk(disk_name, "240MBps", "170MBps");
116 disk->set_sharing_policy(sg4::Disk::Operation::READ, sg4::Disk::SharingPolicy::NONLINEAR,
117 std::bind(&ssd_dynamic_sharing, disk, "read", std::placeholders::_1, std::placeholders::_2));
118 disk->set_sharing_policy(
119 sg4::Disk::Operation::WRITE, sg4::Disk::SharingPolicy::NONLINEAR,
120 std::bind(&ssd_dynamic_sharing, disk, "write", std::placeholders::_1, std::placeholders::_2));
121 disk->set_sharing_policy(sg4::Disk::Operation::READWRITE, sg4::Disk::SharingPolicy::LINEAR);
124 /** @brief Same for a SATA disk, only read operation follows a non-linear resource sharing */
125 static void create_sata_disk(sg4::Host* host, const std::string& disk_name)
127 auto* disk = host->create_disk(disk_name, "68MBps", "50MBps");
128 disk->set_sharing_policy(sg4::Disk::Operation::READ, sg4::Disk::SharingPolicy::NONLINEAR,
129 std::bind(&sata_dynamic_sharing, disk, std::placeholders::_1, std::placeholders::_2));
130 /* this is the default behavior, expliciting only to make it clearer */
131 disk->set_sharing_policy(sg4::Disk::Operation::WRITE, sg4::Disk::SharingPolicy::LINEAR);
132 disk->set_sharing_policy(sg4::Disk::Operation::READWRITE, sg4::Disk::SharingPolicy::LINEAR);
135 int main(int argc, char** argv)
137 sg4::Engine e(&argc, argv);
138 /* simple platform containing 1 host and 2 disk */
139 auto* zone = sg4::create_full_zone("bob_zone");
140 auto* bob = zone->create_host("bob", 1e6);
141 create_ssd_disk(bob, "Edel (SSD)");
142 create_sata_disk(bob, "Griffon (SATA II)");
145 sg4::Actor::create("", bob, host);
148 XBT_INFO("Simulated time: %g", sg4::Engine::get_clock());