Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Use plain pointers instead of references to pointer.
[simgrid.git] / src / plugins / host_energy.cpp
index fe9a948..36e1044 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2021. The SimGrid Team. All rights reserved.          */
+/* Copyright (c) 2010-2023. The SimGrid Team. All rights reserved.          */
 
 /* This program is free software; you can redistribute it and/or modify it
  * under the terms of the license (GNU LGPL) which comes with this package. */
@@ -11,7 +11,8 @@
 #include <simgrid/s4u/VirtualMachine.hpp>
 #include <simgrid/simix.hpp>
 
-#include "src/surf/cpu_interface.hpp"
+#include "src/kernel/resource/CpuImpl.hpp"
+#include "src/simgrid/module.hpp"
 
 #include <boost/algorithm/string/classification.hpp>
 #include <boost/algorithm/string/split.hpp>
@@ -59,14 +60,25 @@ This is enough to compute the wattage as a function of the amount of loaded core
 
    <table border="1">
    <tr><th>#Cores loaded</th><th>Wattage</th><th>Explanation</th></tr>
-   <tr><td>0 (idle)</td><td> 100 Watts&nbsp;</td><td> Idle value</td></tr>
-   <tr><td>0 (not idle)</td><td> 120 Watts</td><td> Epsilon value</td></tr>
+   <tr><td>0 (idle)</td><td> 100 Watts&nbsp;</td><td>Idle value</td></tr>
    <tr><td>1</td><td> 140 Watts</td><td> Linear extrapolation between Epsilon and AllCores</td></tr>
    <tr><td>2</td><td> 160 Watts</td><td> Linear extrapolation between Epsilon and AllCores</td></tr>
    <tr><td>3</td><td> 180 Watts</td><td> Linear extrapolation between Epsilon and AllCores</td></tr>
    <tr><td>4</td><td> 200 Watts</td><td> AllCores value</td></tr>
    </table>
 
+Here is how it looks graphically:
+
+.. image:: img/plugin-energy.svg
+   :scale: 80%
+   :align: center
+
+As you can see, the ``Epsilon`` parameter allows to freely specify the slope you want, while using the 2 parameters
+version of the model (with only ``Idle`` and ``AllCores``) requires that the ``Idle`` value is on the extension of the
+line crossing the consumption you mesure for each core amount. Please note that specifying the consumption for each core
+amount separately was not a solution because parallel tasks can use an amount of cores that is not an integer. The good
+news is that it was not necessary, as our experiments (detailed in the paper) show that the proposed linear model is
+sufficient to capture reality.
 
 .. raw:: html
 
@@ -94,8 +106,8 @@ This encodes the following values:
    </table>
 
 To change the pstate of a given CPU, use the following functions:
-:cpp:func:`MSG_host_get_nb_pstates()`, :cpp:func:`simgrid::s4u::Host::set_pstate()`,
-:cpp:func:`MSG_host_get_power_peak_at()`.
+:cpp:func:`sg_host_get_nb_pstates()`, :cpp:func:`simgrid::s4u::Host::set_pstate()`,
+:cpp:func:`sg_host_get_pstate_speed()`.
 
 .. raw:: html
 
@@ -110,13 +122,12 @@ before you can get accurate energy predictions.
   @endrst
  */
 
-XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_energy, surf, "Logging specific to the SURF energy plugin");
+XBT_LOG_NEW_DEFAULT_SUBCATEGORY(host_energy, kernel, "Logging specific to the host energy plugin");
 
 // Forwards declaration needed to make this function a friend (because friends have external linkage by default)
 static void on_simulation_end();
 
-namespace simgrid {
-namespace plugin {
+namespace simgrid::plugin {
 
 class PowerRange {
 public:
@@ -217,10 +228,10 @@ HostEnergy::HostEnergy(simgrid::s4u::Host* ptr) : host_(ptr)
   const char* off_power_str = host_->get_property("wattage_off");
   if (off_power_str != nullptr) {
     try {
-      this->watts_off_ = std::stod(std::string(off_power_str));
+      this->watts_off_ = std::stod(off_power_str);
     } catch (const std::invalid_argument&) {
-      throw std::invalid_argument(std::string("Invalid value for property wattage_off of host ") + host_->get_cname() +
-                                  ": " + off_power_str);
+      throw std::invalid_argument("Invalid value for property wattage_off of host " + host_->get_name() + ": " +
+                                  off_power_str);
     }
   }
   /* watts_off is 0 by default */
@@ -333,7 +344,7 @@ double HostEnergy::get_current_watts_value(double cpu_load) const
 double HostEnergy::get_consumed_energy()
 {
   if (last_updated_ < simgrid::s4u::Engine::get_clock()) // We need to simcall this as it modifies the environment
-    simgrid::kernel::actor::simcall(std::bind(&HostEnergy::update, this));
+    simgrid::kernel::actor::simcall_answered(std::bind(&HostEnergy::update, this));
 
   return total_energy_;
 }
@@ -391,8 +402,7 @@ void HostEnergy::init_watts_range_list()
 
   has_pstate_power_values_ = true;
 }
-} // namespace plugin
-} // namespace simgrid
+} // namespace simgrid::plugin
 
 using simgrid::plugin::HostEnergy;
 
@@ -410,12 +420,11 @@ static void on_creation(simgrid::s4u::Host& host)
 static void on_action_state_change(simgrid::kernel::resource::CpuAction const& action,
                                    simgrid::kernel::resource::Action::State /*previous*/)
 {
-  for (simgrid::kernel::resource::CpuImpl* const& cpu : action.cpus()) {
+  for (simgrid::kernel::resource::CpuImpl const* cpu : action.cpus()) {
     simgrid::s4u::Host* host = cpu->get_iface();
     if (host != nullptr) {
       // If it's a VM, take the corresponding PM
-      const simgrid::s4u::VirtualMachine* vm = dynamic_cast<simgrid::s4u::VirtualMachine*>(host);
-      if (vm) // If it's a VM, take the corresponding PM
+      if (const auto* vm = dynamic_cast<simgrid::s4u::VirtualMachine*>(host))
         host = vm->get_pm();
 
       // Get the host_energy extension for the relevant host
@@ -477,11 +486,11 @@ void sg_host_energy_plugin_init()
 
   HostEnergy::EXTENSION_ID = simgrid::s4u::Host::extension_create<HostEnergy>();
 
-  simgrid::s4u::Host::on_creation.connect(&on_creation);
-  simgrid::s4u::Host::on_state_change.connect(&on_host_change);
-  simgrid::s4u::Host::on_speed_change.connect(&on_host_change);
-  simgrid::s4u::Host::on_destruction.connect(&on_host_destruction);
-  simgrid::s4u::Engine::on_simulation_end.connect(&on_simulation_end);
+  simgrid::s4u::Host::on_creation_cb(&on_creation);
+  simgrid::s4u::Host::on_state_change_cb(&on_host_change);
+  simgrid::s4u::Host::on_speed_change_cb(&on_host_change);
+  simgrid::s4u::Host::on_destruction_cb(&on_host_destruction);
+  simgrid::s4u::Engine::on_simulation_end_cb(&on_simulation_end);
   simgrid::kernel::resource::CpuAction::on_state_change.connect(&on_action_state_change);
   // We may only have one actor on a node. If that actor executes something like
   //   compute -> recv -> compute
@@ -489,11 +498,10 @@ void sg_host_energy_plugin_init()
   // that the next trigger would be the 2nd compute, hence ignoring the idle time
   // during the recv call. By updating at the beginning of a compute, we can
   // fix that. (If the cpu is not idle, this is not required.)
-  simgrid::s4u::Exec::on_start.connect([](simgrid::s4u::Exec const& activity) {
+  simgrid::s4u::Exec::on_start_cb([](simgrid::s4u::Exec const& activity) {
     if (activity.get_host_number() == 1) { // We only run on one host
       simgrid::s4u::Host* host         = activity.get_host();
-      const simgrid::s4u::VirtualMachine* vm = dynamic_cast<simgrid::s4u::VirtualMachine*>(host);
-      if (vm != nullptr)
+      if (const auto* vm = dynamic_cast<simgrid::s4u::VirtualMachine*>(host))
         host = vm->get_pm();
       xbt_assert(host != nullptr);
       host->extension<HostEnergy>()->update();
@@ -509,7 +517,7 @@ void sg_host_energy_plugin_init()
  */
 void sg_host_energy_update_all()
 {
-  simgrid::kernel::actor::simcall([]() {
+  simgrid::kernel::actor::simcall_answered([]() {
     std::vector<simgrid::s4u::Host*> list = simgrid::s4u::Engine::get_instance()->get_all_hosts();
     for (auto const& host : list)
       if (dynamic_cast<simgrid::s4u::VirtualMachine*>(host) == nullptr) { // Ignore virtual machines