-/* Copyright (c) 2010, 2012-2016. The SimGrid Team. All rights reserved. */
+/* Copyright (c) 2010-2017. 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. */
#include "src/plugins/vm/VirtualMachineImpl.hpp"
#include "src/surf/cpu_interface.hpp"
+#include "simgrid/s4u/Engine.hpp"
+
#include <boost/algorithm/string/classification.hpp>
#include <boost/algorithm/string/split.hpp>
-#include <simgrid/s4u/engine.hpp>
#include <string>
#include <utility>
#include <vector>
simgrid::s4u::Host* host = nullptr;
std::vector<PowerRange>
power_range_watts_list; /*< List of (min_power,max_power) pairs corresponding to each cpu pstate */
+
+ /* We need to keep track of what pstate has been used, as we will sometimes
+ * be notified only *after* a pstate has been used (but we need to update the energy consumption
+ * with the old pstate!)
+ */
+ int pstate = 0;
+
public:
double watts_off = 0.0; /*< Consumption when the machine is turned off (shutdown) */
double total_energy = 0.0; /*< Total energy consumed by the host */
double start_time = this->last_updated;
double finish_time = surf_get_clock();
double cpu_load;
- double current_speed = host->pimpl_cpu->getPstateSpeedCurrent();
+ double current_speed = host->speed();
if (current_speed <= 0)
// Some users declare a pstate of speed 0 flops (e.g., to model boot time).
// We consider that the machine is then fully loaded. That's arbitrary but it avoids a NaN
double previous_energy = this->total_energy;
double instantaneous_consumption;
- if (host->isOff())
+ if (this->pstate == -1) // The host was off at the beginning of this time interval
instantaneous_consumption = this->watts_off;
else
instantaneous_consumption = this->getCurrentWattsValue(cpu_load);
double energy_this_step = instantaneous_consumption * (finish_time - start_time);
+ //TODO Trace: Trace energy_this_step from start_time to finish_time in host->name()
+
this->total_energy = previous_energy + energy_this_step;
this->last_updated = finish_time;
XBT_DEBUG(
"[update_energy of %s] period=[%.2f-%.2f]; current power peak=%.0E flop/s; consumption change: %.2f J -> %.2f J",
host->cname(), start_time, finish_time, host->pimpl_cpu->speed_.peak, previous_energy, energy_this_step);
+
+ /* Save data for the upcoming time interval: whether it's on/off and the pstate if it's on */
+ this->pstate = host->isOn() ? host->pstate() : -1;
}
HostEnergy::HostEnergy(simgrid::s4u::Host* ptr) : host(ptr), last_updated(surf_get_clock())
double HostEnergy::getWattMinAt(int pstate)
{
- xbt_assert(!power_range_watts_list.empty(), "No power range properties specified for host %s", host->cname());
+ xbt_assert(not power_range_watts_list.empty(), "No power range properties specified for host %s", host->cname());
return power_range_watts_list[pstate].min;
}
double HostEnergy::getWattMaxAt(int pstate)
{
- xbt_assert(!power_range_watts_list.empty(), "No power range properties specified for host %s", host->cname());
+ xbt_assert(not power_range_watts_list.empty(), "No power range properties specified for host %s", host->cname());
return power_range_watts_list[pstate].max;
}
/** @brief Computes the power consumed by the host according to the current pstate and processor load */
double HostEnergy::getCurrentWattsValue(double cpu_load)
{
- xbt_assert(!power_range_watts_list.empty(), "No power range properties specified for host %s", host->cname());
+ xbt_assert(not power_range_watts_list.empty(), "No power range properties specified for host %s", host->cname());
/* min_power corresponds to the power consumed when only one core is active */
/* max_power is the power consumed at 100% cpu load */
- auto range = power_range_watts_list.at(host->pstate());
+ auto range = power_range_watts_list.at(this->pstate);
double current_power = 0;
double min_power = 0;
double max_power = 0;
{
if (dynamic_cast<simgrid::s4u::VirtualMachine*>(&host)) // Ignore virtual machines
return;
+
+ //TODO Trace: set to zero the energy variable associated to host->name()
+
host.extension_set(new HostEnergy(&host));
}
{
for (simgrid::surf::Cpu* cpu : action->cpus()) {
simgrid::s4u::Host* host = cpu->getHost();
- if (host == nullptr)
- continue;
+ if (host != nullptr) {
- // If it's a VM, take the corresponding PM
- simgrid::s4u::VirtualMachine* vm = dynamic_cast<simgrid::s4u::VirtualMachine*>(host);
- if (vm) // If it's a VM, take the corresponding PM
- host = vm->pimpl_vm_->getPm();
+ // If it's a VM, take the corresponding PM
+ simgrid::s4u::VirtualMachine* vm = dynamic_cast<simgrid::s4u::VirtualMachine*>(host);
+ if (vm) // If it's a VM, take the corresponding PM
+ host = vm->pimpl_vm_->getPm();
- // Get the host_energy extension for the relevant host
- HostEnergy* host_energy = host->extension<HostEnergy>();
+ // Get the host_energy extension for the relevant host
+ HostEnergy* host_energy = host->extension<HostEnergy>();
- if (host_energy->last_updated < surf_get_clock())
- host_energy->update();
+ if (host_energy->last_updated < surf_get_clock())
+ host_energy->update();
+ }
}
}
-/* This callback is fired either when the host change its state (on/off) or its speed
- * (because the user changed the pstate, or because of external trace events) */
+/* This callback is fired either when the host changes its state (on/off) ("onStateChange") or its speed
+ * (because the user changed the pstate, or because of external trace events) ("onSpeedChange") */
static void onHostChange(simgrid::s4u::Host& host)
{
if (dynamic_cast<simgrid::s4u::VirtualMachine*>(&host)) // Ignore virtual machines
HostEnergy* host_energy = host.extension<HostEnergy>();
- if (host_energy->last_updated < surf_get_clock())
- host_energy->update();
+ host_energy->update();
}
static void onHostDestruction(simgrid::s4u::Host& host)