X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/blobdiff_plain/82230d737404aa70c3c2b5824d97109f1f129d58..e3b7b40594af0c6cae13e79ace27da724740fcf6:/src/surf/plugins/link_energy.cpp
diff --git a/src/surf/plugins/link_energy.cpp b/src/surf/plugins/link_energy.cpp
index f7bc8ebcc4..34e71ae6fc 100644
--- a/src/surf/plugins/link_energy.cpp
+++ b/src/surf/plugins/link_energy.cpp
@@ -17,14 +17,14 @@
/** @addtogroup SURF_plugin_energy
- This is the energy plugin, enabling to account for the dissipated energy in the simulated platform.
+ This is the link energy plugin, accounting for the dissipated energy in the simulated platform.
The energy consumption of a link depends directly on its current traffic load. Specify that consumption in your
platform file as follows:
\verbatim
-
-
+
+
\endverbatim
@@ -36,7 +36,7 @@
To simulate the energy-related elements, first call the simgrid#energy#sg_link_energy_plugin_init() before your
#MSG_init(),
- and then use the following function to retrieve the consumption of a given link: MSG_link_get_consumed_energy().
+ and then use the following function to retrieve the consumption of a given link: sg_link_get_consumed_energy().
*/
XBT_LOG_NEW_DEFAULT_SUBCATEGORY(link_energy, surf, "Logging specific to the SURF LinkEnergy plugin");
@@ -44,14 +44,6 @@ XBT_LOG_NEW_DEFAULT_SUBCATEGORY(link_energy, surf, "Logging specific to the SURF
namespace simgrid {
namespace plugin {
-class LinkPowerRange {
-public:
- double idle;
- double busy;
-
- LinkPowerRange(double idle, double busy) : idle(idle), busy(busy) {}
-};
-
class LinkEnergy {
public:
static simgrid::xbt::Extension EXTENSION_ID;
@@ -59,25 +51,26 @@ public:
explicit LinkEnergy(simgrid::s4u::Link* ptr);
~LinkEnergy();
- double getALinkTotalPower();
void initWattsRangeList();
- double getTotalEnergy();
+ double getConsumedEnergy();
void update();
private:
double getPower();
- simgrid::s4u::Link* link{};
+ simgrid::s4u::Link* link_{};
- std::vector power_range_watts_list{};
+ bool inited_{false};
+ double idle_{0.0};
+ double busy_{0.0};
- double total_energy{0.0};
- double last_updated{0.0}; /*< Timestamp of the last energy update event*/
+ double totalEnergy_{0.0};
+ double lastUpdated_{0.0}; /*< Timestamp of the last energy update event*/
};
simgrid::xbt::Extension LinkEnergy::EXTENSION_ID;
-LinkEnergy::LinkEnergy(simgrid::s4u::Link* ptr) : link(ptr), last_updated(surf_get_clock())
+LinkEnergy::LinkEnergy(simgrid::s4u::Link* ptr) : link_(ptr), lastUpdated_(surf_get_clock())
{
}
@@ -87,17 +80,18 @@ void LinkEnergy::update()
{
double power = getPower();
double now = surf_get_clock();
- total_energy += power * (now - last_updated);
- last_updated = now;
+ totalEnergy_ += power * (now - lastUpdated_);
+ lastUpdated_ = now;
}
void LinkEnergy::initWattsRangeList()
{
- if (!power_range_watts_list.empty())
+ if (inited_)
return;
+ inited_ = true;
- const char* all_power_values_str = this->link->getProperty("watt_range");
+ const char* all_power_values_str = this->link_->getProperty("watt_range");
if (all_power_values_str == nullptr)
return;
@@ -109,23 +103,20 @@ void LinkEnergy::initWattsRangeList()
/* retrieve the power values associated */
std::vector current_power_values;
boost::split(current_power_values, current_power_values_str, boost::is_any_of(":"));
- xbt_assert(current_power_values.size() == 2, "Power properties incorrectly defined - "
- "could not retrieve idle and busy power values for link %s",
- this->link->getCname());
+ xbt_assert(current_power_values.size() == 2,
+ "Power properties incorrectly defined - could not retrieve idle and busy power values for link %s",
+ this->link_->getCname());
/* min_power corresponds to the idle power (link load = 0) */
/* max_power is the power consumed at 100% link load */
- char* idle = bprintf("Invalid idle power value for link%s", this->link->getCname());
- char* busy = bprintf("Invalid busy power value for %s", this->link->getCname());
-
- double idleVal = xbt_str_parse_double((current_power_values.at(0)).c_str(), idle);
-
- double busyVal = xbt_str_parse_double((current_power_values.at(1)).c_str(), busy);
+ char* idleMsg = bprintf("Invalid idle power value for link%s", this->link_->getCname());
+ char* busyMsg = bprintf("Invalid busy power value for %s", this->link_->getCname());
- this->power_range_watts_list.push_back(LinkPowerRange(idleVal, busyVal));
+ idle_ = xbt_str_parse_double((current_power_values.at(0)).c_str(), idleMsg);
+ busy_ = xbt_str_parse_double((current_power_values.at(1)).c_str(), busyMsg);
- xbt_free(idle);
- xbt_free(busy);
+ xbt_free(idleMsg);
+ xbt_free(busyMsg);
update();
}
}
@@ -133,26 +124,22 @@ void LinkEnergy::initWattsRangeList()
double LinkEnergy::getPower()
{
- if (power_range_watts_list.empty())
+ if (!inited_)
return 0.0;
- auto range = power_range_watts_list[0];
+ double power_slope = busy_ - idle_;
- double busy = range.busy;
- double idle = range.idle;
-
- double power_slope = busy - idle;
-
- double normalized_link_usage = link->getUsage() / link->bandwidth();
+ double normalized_link_usage = link_->getUsage() / link_->bandwidth();
double dynamic_power = power_slope * normalized_link_usage;
- return idle + dynamic_power;
+ return idle_ + dynamic_power;
}
-double LinkEnergy::getTotalEnergy()
+double LinkEnergy::getConsumedEnergy()
{
- update();
- return this->total_energy;
+ if (lastUpdated_ < surf_get_clock()) // We need to simcall this as it modifies the environment
+ simgrid::simix::kernelImmediate(std::bind(&LinkEnergy::update, this));
+ return this->totalEnergy_;
}
}
}
@@ -160,12 +147,6 @@ double LinkEnergy::getTotalEnergy()
using simgrid::plugin::LinkEnergy;
/* **************************** events callback *************************** */
-static void onCreation(simgrid::s4u::Link& link)
-{
- XBT_DEBUG("onCreation is called for link: %s", link.getCname());
- link.extension_set(new LinkEnergy(&link));
-}
-
static void onCommunicate(simgrid::surf::NetworkAction* action, simgrid::s4u::Host* src, simgrid::s4u::Host* dst)
{
XBT_DEBUG("onCommunicate is called");
@@ -175,67 +156,31 @@ static void onCommunicate(simgrid::surf::NetworkAction* action, simgrid::s4u::Ho
continue;
XBT_DEBUG("Update link %s", link->getCname());
- // Get the link_energy extension for the relevant link
LinkEnergy* link_energy = link->piface_.extension();
link_energy->initWattsRangeList();
link_energy->update();
}
}
-static void onActionStateChange(simgrid::surf::NetworkAction* action)
-{
- XBT_DEBUG("onActionStateChange is called");
- for (simgrid::surf::LinkImpl* link : action->links()) {
-
- if (link == nullptr)
- continue;
-
- // Get the link_energy extension for the relevant link
- LinkEnergy* link_energy = link->piface_.extension();
- link_energy->update();
- }
-}
-
-static void onLinkStateChange(simgrid::s4u::Link& link)
-{
- XBT_DEBUG("onLinkStateChange is called for link: %s", link.getCname());
-
- LinkEnergy* link_energy = link.extension();
- link_energy->update();
-}
-
-static void onLinkDestruction(simgrid::s4u::Link& link)
+static void onSimulationEnd()
{
- XBT_DEBUG("onLinkDestruction is called for link: %s", link.getCname());
+ std::vector links;
+ simgrid::s4u::Engine::getInstance()->getLinkList(&links);
- LinkEnergy* link_energy = link.extension();
- link_energy->update();
-}
-
-static void computeAndDisplayTotalEnergy()
-{
- std::vector link_list;
- simgrid::s4u::Engine::getInstance()->getLinkList(&link_list);
double total_energy = 0.0; // Total dissipated energy (whole platform)
- for (const auto link : link_list) {
- LinkEnergy* link_energy = link->extension();
-
- double a_link_total_energy = link_energy->getTotalEnergy();
- total_energy += a_link_total_energy;
- const char* name = link->getCname();
- if (strcmp(name, "__loopback__"))
- XBT_INFO("Link '%s' total consumption: %f", name, a_link_total_energy);
+ for (const auto link : links) {
+ double link_energy = link->extension()->getConsumedEnergy();
+ total_energy += link_energy;
}
XBT_INFO("Total energy over all links: %f", total_energy);
}
-
-static void onSimulationEnd()
-{
- computeAndDisplayTotalEnergy();
-}
/* **************************** Public interface *************************** */
SG_BEGIN_DECL()
+int sg_link_energy_is_inited()
+{
+ return LinkEnergy::EXTENSION_ID.valid();
+}
/** \ingroup SURF_plugin_energy
* \brief Enable energy plugin
* \details Enable energy plugin to get joules consumption of each cpu. You should call this function before
@@ -248,12 +193,42 @@ void sg_link_energy_plugin_init()
return;
LinkEnergy::EXTENSION_ID = simgrid::s4u::Link::extension_create();
- simgrid::s4u::Link::onCreation.connect(&onCreation);
- simgrid::s4u::Link::onStateChange.connect(&onLinkStateChange);
- simgrid::s4u::Link::onDestruction.connect(&onLinkDestruction);
- simgrid::s4u::Link::onCommunicationStateChange.connect(&onActionStateChange);
+ xbt_assert(sg_host_count() == 0, "Please call sg_link_energy_plugin_init() before initializing the platform.");
+
+ simgrid::s4u::Link::onCreation.connect([](simgrid::s4u::Link& link) {
+ link.extension_set(new LinkEnergy(&link));
+ });
+
+ simgrid::s4u::Link::onStateChange.connect([](simgrid::s4u::Link& link) {
+ link.extension()->update();
+ });
+
+ simgrid::s4u::Link::onDestruction.connect([](simgrid::s4u::Link& link) {
+ if (strcmp(link.getCname(), "__loopback__"))
+ XBT_INFO("Energy consumption of link '%s': %f Joules", link.getCname(),
+ link.extension()->getConsumedEnergy());
+ });
+
+ simgrid::s4u::Link::onCommunicationStateChange.connect([](simgrid::surf::NetworkAction* action) {
+ for (simgrid::surf::LinkImpl* link : action->links()) {
+ if (link != nullptr)
+ link->piface_.extension()->update();
+ }
+ });
+
simgrid::s4u::Link::onCommunicate.connect(&onCommunicate);
simgrid::s4u::onSimulationEnd.connect(&onSimulationEnd);
}
+/** @ingroup plugin_energy
+ * @brief Returns the total energy consumed by the link so far (in Joules)
+ *
+ * Please note that since the consumption is lazily updated, it may require a simcall to update it.
+ * The result is that the actor requesting this value will be interrupted,
+ * the value will be updated in kernel mode before returning the control to the requesting actor.
+ */
+double sg_link_get_consumed_energy(sg_link_t link)
+{
+ return link->extension()->getConsumedEnergy();
+}
SG_END_DECL()