X-Git-Url: https://bilbo.iut-bm.univ-fcomte.fr/and/gitweb/loba.git/blobdiff_plain/23529d55ccbfd0a851fdc86708320811ddda8ec4..2e3129cd655efb5ccfa93000546cefd02b725154:/process.cpp diff --git a/process.cpp b/process.cpp index 0544b21..57c0661 100644 --- a/process.cpp +++ b/process.cpp @@ -1,7 +1,6 @@ #include #include #include -#include #include #include #include @@ -11,6 +10,7 @@ XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(proc); #include "misc.h" #include "options.h" +#include "tracing.h" #include "process.h" @@ -20,7 +20,7 @@ double process::total_load_exit = 0.0; process::process(int argc, char* argv[]) { - if (argc < 2 || !(std::istringstream(argv[1]) >> load)) + if (argc < 2 || !(std::istringstream(argv[1]) >> real_load)) throw std::invalid_argument("bad or missing initial load parameter"); neigh.assign(argv + 2, argv + argc); @@ -35,15 +35,17 @@ process::process(int argc, char* argv[]) comp = 0.0; - prev_load_broadcast = -1; // force sending of load on first send() - expected_load = load; - total_load_running += load; - total_load_init += load; + prev_load_broadcast = -1; // force sending of load on first send_all() + expected_load = real_load; + total_load_running += real_load; + total_load_init += real_load; ctrl_close_pending = data_close_pending = neigh.size(); close_received = false; finalizing = false; + comp_iter = lb_iter = 0; + e_xbt_log_priority_t logp = xbt_log_priority_verbose; if (!LOG_ISENABLED(logp)) return; @@ -62,48 +64,51 @@ process::process(int argc, char* argv[]) process::~process() { - total_load_exit += load; + total_load_exit += real_load; + if (opt::bookkeeping) { + INFO4("Final load after %d:%d iterations: %g ; expected: %g", + lb_iter, comp_iter, real_load, expected_load); + } else { + INFO2("Final load after %d iterations: %g", + lb_iter, real_load); + if (lb_iter != comp_iter) + WARN2("lb_iter (%d) and comp_iter (%d) differ!", + lb_iter, comp_iter); + } + VERB1("Total computation for this process: %g", comp); } int process::run() { double next_iter_after_date = 0.0; - INFO1("Initial load: %g", load); + INFO1("Initial load: %g", real_load); VERB0("Starting..."); - comp_iter = lb_iter = 0; while (true) { - if (opt::min_iter_duration) { + if (get_load() > 0.0) { double now = MSG_get_clock(); - if (now < next_iter_after_date){ - double delay = next_iter_after_date - now; - DEBUG1("sleeping for %g s", delay); - MSG_process_sleep(delay); - } + if (now < next_iter_after_date) + MSG_process_sleep(next_iter_after_date - now); next_iter_after_date = MSG_get_clock() + opt::min_iter_duration; - } - double ld = lb_load(); - if (ld > 0.0) { ++lb_iter; if (opt::log_rate && lb_iter % opt::log_rate == 0) { if (opt::bookkeeping) INFO4("(%u:%u) current load: %g ; expected: %g", - lb_iter, comp_iter, load, expected_load); + lb_iter, comp_iter, real_load, expected_load); else INFO2("(%u) current load: %g", - lb_iter, load); + lb_iter, real_load); } - ld -= load_balance(ld); + load_balance(); print_loads(true, xbt_log_priority_debug); } - lb_load() = ld; // send load information, and load (data) if any - send(); - if (load > 0.0) { + send_all(); + if (real_load > 0.0) { ++comp_iter; compute(); } @@ -123,8 +128,14 @@ int process::run() // block on receiving unless there is something to compute or // to send - bool wait = (load == 0 && lb_load() == prev_load_broadcast); - receive(wait); + double timeout; + if (real_load != 0 || get_load() != prev_load_broadcast) + timeout = 0.0; + else if (opt::min_iter_duration) + timeout = opt::min_iter_duration; + else + timeout = 1.0; + receive(timeout); // one of our neighbor is finalizing if (opt::exit_on_close && close_received) { @@ -133,7 +144,7 @@ int process::run() } // have no load and cannot receive anything - if (load == 0.0 && !may_receive()) { + if (real_load == 0.0 && !may_receive()) { VERB0("I'm a poor lonesome process, and I have no load..."); break; } @@ -159,42 +170,21 @@ int process::run() */ VERB0("Done."); - if (opt::bookkeeping) { - INFO4("Final load after %d:%d iterations: %g ; expected: %g", - lb_iter, comp_iter, load, expected_load); - } else { - INFO2("Final load after %d iterations: %g", - lb_iter, load); - if (lb_iter != comp_iter) - WARN2("lb_iter (%d) and comp_iter (%d) differ!", - lb_iter, comp_iter); - } return 0; } -double process::sum_of_to_send() const -{ - using std::tr1::bind; - using std::tr1::placeholders::_1; - using std::tr1::placeholders::_2; - - return std::accumulate(neigh.begin(), neigh.end(), 0.0, - bind(std::plus(), - _1, bind(&neighbor::get_to_send, _2))); -} - -double process::load_balance(double /*my_load*/) +void process::load_balance() { if (lb_iter == 1) // warn only once WARN0("process::load_balance() is a no-op!"); - return 0.0; } void process::compute() { - if (load > 0.0) { - double flops = opt::comp_cost(load); + if (real_load > 0.0) { + double flops = opt::comp_cost(real_load); m_task_t task = MSG_task_create("computation", flops, 0.0, NULL); + TRACE_msg_set_task_category(task, TRACE_CAT_COMP); DEBUG2("compute %g flop%s", flops, ESSE(flops)); MSG_task_execute(task); comp += flops; @@ -204,10 +194,17 @@ void process::compute() } } +void process::send(neighbor& nb, double amount) +{ + set_load(get_load() - amount); + nb.set_to_send(nb.get_to_send() + amount); + nb.set_load(nb.get_load() + amount); // fixme: make this optional? +} + void process::send1_no_bookkeeping(neighbor& nb) { - if (load != prev_load_broadcast) - comm.send(nb.get_ctrl_mbox(), new message(message::INFO, load)); + if (real_load != prev_load_broadcast) + comm.send(nb.get_ctrl_mbox(), new message(message::INFO, real_load)); double load_to_send = nb.get_to_send(); if (load_to_send > 0.0) { comm.send(nb.get_data_mbox(), new message(message::LOAD, load_to_send)); @@ -231,20 +228,20 @@ void process::send1_bookkeeping(neighbor& nb) } else { new_debt = nb.get_debt(); } - if (load <= new_debt) { - load_to_send = load; + if (real_load <= new_debt) { + load_to_send = real_load; nb.set_debt(new_debt - load_to_send); - load = 0.0; + real_load = 0.0; } else { load_to_send = new_debt; nb.set_debt(0.0); - load -= load_to_send; + real_load -= load_to_send; } if (load_to_send > 0.0) comm.send(nb.get_data_mbox(), new message(message::LOAD, load_to_send)); } -void process::send() +void process::send_all() { using std::tr1::bind; using std::tr1::placeholders::_1; @@ -256,18 +253,18 @@ void process::send() } else { std::for_each(neigh.begin(), neigh.end(), bind(&process::send1_no_bookkeeping, this, _1)); - prev_load_broadcast = load; + prev_load_broadcast = real_load; } comm.flush(false); } -void process::receive(bool wait) +void process::receive(double timeout) { message* msg; m_host_t from; - DEBUG1("%sblocking receive", "\0non-" + !wait); - while (may_receive() && comm.recv(msg, from, wait)) { + DEBUG2("%sblocking receive (%g)", "\0non-" + !timeout, timeout); + while (may_receive() && comm.recv(msg, from, timeout)) { switch (msg->get_type()) { case message::INFO: { neighbor* n = rev_neigh[from]; @@ -279,7 +276,7 @@ void process::receive(bool wait) break; case message::LOAD: { double ld = msg->get_amount(); - load += ld; + real_load += ld; if (finalizing) total_load_running -= ld; break; @@ -294,7 +291,7 @@ void process::receive(bool wait) break; } delete msg; - wait = false; // only wait on first recv + timeout = 0.0; // only wait on first recv } comm.flush(false); } @@ -311,18 +308,18 @@ void process::finalize() using std::tr1::placeholders::_1; finalizing = true; - total_load_running -= load; + total_load_running -= real_load; DEBUG2("send CLOSE to %lu neighbor%s", (unsigned long )neigh.size(), ESSE(neigh.size())); std::for_each(neigh.begin(), neigh.end(), bind(&process::finalize1, this, _1)); - DEBUG2("wait for CLOSE from %lu neighbor%s", - (unsigned long )neigh.size(), ESSE(neigh.size())); while (may_receive()) { comm.flush(false); - receive(true); + DEBUG2("waiting for %d CTRL and %d DATA CLOSE", + ctrl_close_pending, data_close_pending); + receive(-1.0); } comm.flush(true);