Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Disk: Non-linear contraints
[simgrid.git] / examples / cpp / io-degradation / s4u-io-degradation.cpp
1 /* Copyright (c) 2017-2021. The SimGrid Team. All rights reserved.          */
2
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. */
5
6 /* This example shows how to simulate a non-linear resource sharing for disk
7  * operations.
8  *
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
12  *
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).
15  */
16
17 #include <simgrid/s4u.hpp>
18
19 namespace sg4 = simgrid::s4u;
20
21 XBT_LOG_NEW_DEFAULT_CATEGORY(disk_test, "Messages specific for this simulation");
22
23 /** @brief Calculates the bandwidth for disk doing async operations */
24 static void estimate_bw(sg4::Disk* disk, int n_flows, bool read)
25 {
26   unsigned long long size = 100000;
27   double cur_time         = sg4::Engine::get_clock();
28   std::vector<sg4::IoPtr> activities;
29   for (int i = 0; i < n_flows; i++) {
30     sg4::IoPtr act;
31     if (read)
32       act = disk->read_async(size);
33     else
34       act = disk->write_async(size);
35
36     activities.push_back(act);
37   }
38
39   for (auto& act : activities)
40     act->wait();
41
42   double elapsed_time = sg4::Engine::get_clock() - cur_time;
43   double estimated_bw = size * n_flows / elapsed_time;
44   XBT_INFO("Disk: %s, concurrent %s: %d, estimated bandwidth: %lf", disk->get_cname(), read ? "read" : "write", n_flows,
45            estimated_bw);
46 }
47
48 static void host()
49 {
50   /* - Estimating bw for each disk and considering concurrent flows */
51   for (int n = 1; n < 15; n += 2) {
52     for (auto* disk : sg4::Host::current()->get_disks()) {
53       estimate_bw(disk, n, true);
54       estimate_bw(disk, n, false);
55     }
56   }
57 }
58
59 /**
60  * @brief Non-linear resource callback for SSD disks
61  *
62  * In this case, we have measurements for some resource sharing and directly use them to return the
63  * correct value
64  * @param disk Disk on which the operation is happening (defined by the user through the std::bind)
65  * @param op read or write operation (defined by the user through the std::bind)
66  * @param capacity Resource current capacity in SimGrid
67  * @param n Number of activities sharing this resource
68  */
69 static double ssd_dynamic_sharing(const sg4::Disk* disk, const std::string& op, double capacity, int n)
70 {
71   /* measurements for SSD disks */
72   using DiskCapacity                                                   = std::unordered_map<int, double>;
73   static const std::unordered_map<std::string, DiskCapacity> SSD_SPEED = {{"write", {{1, 131.}}},
74                                                                           {"read",
75                                                                            {{1, 152.},
76                                                                             {2, 161.},
77                                                                             {3, 184.},
78                                                                             {4, 197.},
79                                                                             {5, 207.},
80                                                                             {6, 215.},
81                                                                             {7, 220.},
82                                                                             {8, 224.},
83                                                                             {9, 227.},
84                                                                             {10, 231.},
85                                                                             {11, 233.},
86                                                                             {12, 235.},
87                                                                             {13, 237.},
88                                                                             {14, 238.},
89                                                                             {15, 239.}}}};
90
91   const auto& data = SSD_SPEED.at(op);
92   /* no special bandwidth for this disk sharing N flows, just returns maximal capacity */
93   if (data.find(n) != data.end())
94     capacity = data.at(n);
95
96   // XBT_INFO("Disk %s, %s operation between %d flows, capacity %lf", disk->get_cname(), op.c_str(), n, capacity);
97
98   return capacity;
99 }
100
101 /**
102  * @brief Non-linear resource callback for SATA disks
103  *
104  * In this case, the degradation for read operations is linear and we have a formula that represents it.
105  *
106  * @param disk Disk on which the operation is happening (defined by the user through the std::bind)
107  * @param capacity Resource current capacity in SimGrid
108  * @param n Number of activities sharing this resource
109  */
110 static double sata_dynamic_sharing(const sg4::Disk* disk, double capacity, int n)
111 {
112   capacity = 68.3 - 1.7 * n;
113   // XBT_INFO("Disk %s, read operation between %d flows, capacity %lf", disk->get_cname(), n, capacity);
114
115   return capacity;
116 }
117
118 /** @brief Creates an SSD disk, setting the appropriate callback for non-linear resource sharing */
119 static void create_ssd_disk(sg4::Host* host, const std::string& disk_name)
120 {
121   auto* disk = host->create_disk(disk_name, "240MBps", "170MBps");
122   disk->set_sharing_policy(sg4::Disk::Operation::READ, sg4::Disk::SharingPolicy::NONLINEAR,
123                            std::bind(&ssd_dynamic_sharing, disk, "read", std::placeholders::_1, std::placeholders::_2));
124   disk->set_sharing_policy(
125       sg4::Disk::Operation::WRITE, sg4::Disk::SharingPolicy::NONLINEAR,
126       std::bind(&ssd_dynamic_sharing, disk, "write", std::placeholders::_1, std::placeholders::_2));
127   disk->set_sharing_policy(sg4::Disk::Operation::READWRITE, sg4::Disk::SharingPolicy::LINEAR);
128 }
129
130 /** @brief Same for a SATA disk, only read operation follows a non-linear resource sharing */
131 static void create_sata_disk(sg4::Host* host, const std::string& disk_name)
132 {
133   auto* disk = host->create_disk(disk_name, "68MBps", "50MBps");
134   disk->set_sharing_policy(sg4::Disk::Operation::READ, sg4::Disk::SharingPolicy::NONLINEAR,
135                            std::bind(&sata_dynamic_sharing, disk, std::placeholders::_1, std::placeholders::_2));
136   /* this is the default behavior, expliciting only to make it clearer */
137   disk->set_sharing_policy(sg4::Disk::Operation::WRITE, sg4::Disk::SharingPolicy::LINEAR);
138   disk->set_sharing_policy(sg4::Disk::Operation::READWRITE, sg4::Disk::SharingPolicy::LINEAR);
139 }
140
141 int main(int argc, char** argv)
142 {
143   sg4::Engine e(&argc, argv);
144   /* simple platform containing 1 host and 2 disk */
145   auto* zone = sg4::create_full_zone("bob_zone");
146   auto* bob  = zone->create_host("bob", 1e6);
147   create_ssd_disk(bob, "Edel (SSD)");
148   create_sata_disk(bob, "Griffon (SATA II)");
149   zone->seal();
150
151   simgrid::s4u::Actor::create("", bob, host);
152
153   e.run();
154   XBT_INFO("Simulated time: %g", simgrid::s4u::Engine::get_clock());
155
156   return 0;
157 }