From: Martin Quinson Date: Tue, 13 Jun 2017 15:20:49 +0000 (+0200) Subject: Energy: New function to update the consumption of all hosts at once X-Git-Tag: v3.16~119^2 X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/commitdiff_plain/8a714c0ee28c49ac13a74a596238f9fa4bd9f603 Energy: New function to update the consumption of all hosts at once --- diff --git a/ChangeLog b/ChangeLog index 21cd08737c..4d92bbf49a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -30,6 +30,9 @@ SimGrid (3.16) UNRELEASED Virtual Machines - Allow multicore VMs, along with the correct sharing computations + Energy + - New function to update the consumption of all hosts at once. + MSG - The netzone are now available from the MSG API. The old names still work, but are now deprecated. diff --git a/include/simgrid/plugins/energy.h b/include/simgrid/plugins/energy.h index 06d1de8fd4..bc1da109dc 100644 --- a/include/simgrid/plugins/energy.h +++ b/include/simgrid/plugins/energy.h @@ -13,6 +13,7 @@ SG_BEGIN_DECL() XBT_PUBLIC(void) sg_host_energy_plugin_init(); +XBT_PUBLIC(void) sg_host_energy_update_all(); XBT_PUBLIC(double) sg_host_get_consumed_energy(sg_host_t host); XBT_PUBLIC(double) sg_host_get_wattmin_at(sg_host_t host, int pstate); XBT_PUBLIC(double) sg_host_get_wattmax_at(sg_host_t host, int pstate); diff --git a/src/bindings/java/jmsg_host.cpp b/src/bindings/java/jmsg_host.cpp index 2cf5b28ff7..2676d37ff9 100644 --- a/src/bindings/java/jmsg_host.cpp +++ b/src/bindings/java/jmsg_host.cpp @@ -336,6 +336,11 @@ JNIEXPORT void JNICALL Java_org_simgrid_msg_Host_setAsyncMailbox(JNIEnv * env, j env->ReleaseStringUTFChars((jstring) jname, name); } +JNIEXPORT void JNICALL Java_org_simgrid_msg_Host_updateAllEnergyConsumptions(JNIEnv* env, jclass cls) +{ + sg_host_energy_update_all(); +} + JNIEXPORT jdouble JNICALL Java_org_simgrid_msg_Host_getConsumedEnergy (JNIEnv *env, jobject jhost) { msg_host_t host = jhost_get_native(env, jhost); diff --git a/src/bindings/java/jmsg_host.h b/src/bindings/java/jmsg_host.h index ebbc41e868..0b9ed50145 100644 --- a/src/bindings/java/jmsg_host.h +++ b/src/bindings/java/jmsg_host.h @@ -59,6 +59,7 @@ JNIEXPORT jobjectArray JNICALL Java_org_simgrid_msg_Host_getStorageContent(JNIEn JNIEXPORT jobjectArray JNICALL Java_org_simgrid_msg_Host_all(JNIEnv *env, jclass cls); JNIEXPORT void JNICALL Java_org_simgrid_msg_Host_setAsyncMailbox(JNIEnv * env, jclass cls_arg, jobject jname); +JNIEXPORT void JNICALL Java_org_simgrid_msg_Host_updateAllEnergyConsumptions(JNIEnv* env, jclass cls); JNIEXPORT jdouble JNICALL Java_org_simgrid_msg_Host_getConsumedEnergy (JNIEnv *env, jobject jhost); JNIEXPORT void JNICALL Java_org_simgrid_msg_Host_setPstate(JNIEnv* env, jobject jhost, jint pstate); diff --git a/src/bindings/java/org/simgrid/msg/Host.java b/src/bindings/java/org/simgrid/msg/Host.java index 9165a10316..2e39fe2d43 100644 --- a/src/bindings/java/org/simgrid/msg/Host.java +++ b/src/bindings/java/org/simgrid/msg/Host.java @@ -133,7 +133,17 @@ public class Host { /** This methods returns the list of storages (names) attached to an host */ public native String[] getAttachedStorage(); - /** Returns the amount of Joules consumed by that host so far */ + /** After this call, sg_host_get_consumed_energy() will not interrupt your process + * (until after the next clock update). + */ + static public native void updateAllEnergyConsumptions(); + /** Returns the amount of Joules consumed by that host so far + * + * 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. + + */ public native double getConsumedEnergy(); /** Returns the current pstate */ diff --git a/src/surf/plugins/host_energy.cpp b/src/surf/plugins/host_energy.cpp index 9a441b93ac..f7878d7b11 100644 --- a/src/surf/plugins/host_energy.cpp +++ b/src/surf/plugins/host_energy.cpp @@ -113,45 +113,54 @@ void HostEnergy::update() double finish_time = surf_get_clock(); double cpu_load; 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 - cpu_load = 1; - else - cpu_load = lmm_constraint_get_usage(host->pimpl_cpu->constraint()) / current_speed; - - /** Divide by the number of cores here **/ - cpu_load /= host->pimpl_cpu->coreCount(); - - if (cpu_load > 1) // A machine with a load > 1 consumes as much as a fully loaded machine, not more - cpu_load = 1; - - /* The problem with this model is that the load is always 0 or 1, never something less. - * Another possibility could be to model the total energy as - * - * X/(X+Y)*W_idle + Y/(X+Y)*W_burn - * - * where X is the amount of idling cores, and Y the amount of computing cores. - */ - double previous_energy = this->total_energy; + if (start_time < finish_time) { + // We may have start == finish if the past consumption was updated since the simcall was started + // for example if 2 actors requested to update the same host's consumption in a given scheduling round. + // + // Even in this case, we need to save the pstate for the next call (after this big if), + // which may have changed since that recent update. + + 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 + cpu_load = 1; + else + cpu_load = lmm_constraint_get_usage(host->pimpl_cpu->constraint()) / current_speed; + + /** Divide by the number of cores here **/ + cpu_load /= host->pimpl_cpu->coreCount(); - double instantaneous_consumption; - 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); + if (cpu_load > 1) // A machine with a load > 1 consumes as much as a fully loaded machine, not more + cpu_load = 1; - double energy_this_step = instantaneous_consumption * (finish_time - start_time); + /* The problem with this model is that the load is always 0 or 1, never something less. + * Another possibility could be to model the total energy as + * + * X/(X+Y)*W_idle + Y/(X+Y)*W_burn + * + * where X is the amount of idling cores, and Y the amount of computing cores. + */ + + double previous_energy = this->total_energy; + + double instantaneous_consumption; + 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); - //TODO Trace: Trace energy_this_step from start_time to finish_time in host->name() + double energy_this_step = instantaneous_consumption * (finish_time - start_time); - this->total_energy = previous_energy + energy_this_step; - this->last_updated = finish_time; + // TODO Trace: Trace energy_this_step from start_time to finish_time in host->name() - 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); + 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; @@ -372,7 +381,26 @@ void sg_host_energy_plugin_init() simgrid::surf::CpuAction::onStateChange.connect(&onActionStateChange); } +/** @brief updates the consumption of all hosts + * + * After this call, sg_host_get_consumed_energy() will not interrupt your process + * (until after the next clock update). + */ +void sg_host_energy_update_all() +{ + simgrid::simix::kernelImmediate([]() { + std::vector list; + simgrid::s4u::Engine::instance()->hostList(&list); + for (auto host : list) + host->extension()->update(); + }); +} + /** @brief Returns the total energy consumed by the host 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. * * See also @ref SURF_plugin_energy. */