Commit 5a72226d authored by Robert Ricci's avatar Robert Ricci

A faily fundamental change in assign - change the criteria we use

to accept new solutions, so that we don't give violtions any special
treatment.

This can greatly reduce 'thrasing' at low scores, allowing assign to
converge on a solution much faster. For example, in the 1000-node
topology used for the virtualization paper, assign's runtime dropped
from nearly two hours to just over half an hour, with no degredation
in scores found.

You can get the old accept behavior by enabling the
SPECIAL_VIOLATION_TREATMENT #define, which is on right now (hence, we
are not using this change yet.)

Here are the pertinent comments from the code:

#ifdef SPECIAL_VIOLATION_TREATMENT
         /*
          * In this ifdef, we always accept new solutions that have fewer
          * violations than the old solution, and when we're trying to
          * determine whether or not to accept a new solution with a higher
          * score, we don't take violations into the account.
          *
          * The problem with this shows up at low temperatures. What can often
          * happen is that we accept a solution with worse violations but a
          * better (or similar) score. Then, if we were to try, say the first
          * solution (or a score-equivalent one) again, we'd accept it again.
          *
          * What this leads to is 'thrashing', where we have a whole lot of
          * variation of scores over time, but are not making any real
          * progress. This prevents the cooling schedule from converging for
          * much, much longer than it should really take.
          */
#else // no SPECIAL_VIOLATION_TREATMENT
         /*
          * In this branch of the ifdef, we give violations no special
          * treatment when it comes to accepting new solution - we just add
          * them into the score. This makes assign behave in a more 'classic'
          * simulated annealing manner.
          *
          * One consequence, though, is that we have to be more careful with
          * scores. We do not want to be able to get into a situation where
          * adding a violation results in a _lower_ score than a solution with
          * fewer violations.
          */
parent 9d3ee9c6
......@@ -52,6 +52,8 @@ CXXFLAGS += -DPER_VNODE_TT
CXXFLAGS += -DFIX_PLINK_ENDPOINTS
# Allow pnodes to cap the amount of trivial link bandwidth they can handle
CXXFLAGS += -DTRIVIAL_LINK_BW
# Use the old acceptance criteria, which gives special treatment to violations
#CXXFLAGS += -DSPECIAL_VIOLATION_TREATMENT
# If you're looking to turn on or off USE_OPTIMAL, its now a cmdline
# option. Use OP={0,1} on the command line at run time... :)
......
......@@ -90,6 +90,9 @@ inline bool pnode_is_match(tb_vnode *vn, tb_pnode *pn) {
if ((pn->current_type_record->current_load + vn->typecount) >
pn->current_type_record->max_load) {
// This would put us over its max load
//if (allow_overload && (tr->max_load > 1) &&
// ((pn->current_type_record->current_load + vn->typecount) <
// (pn->current_type_record->max_load + 2))) {
if (allow_overload && (tr->max_load > 1)) {
// That's okay, we're allowing overload
matched = true;
......@@ -802,7 +805,7 @@ void anneal(bool scoring_selftest, double scale_neighborhood,
} else if (melting) {
accepttrans = true;
RDEBUG(cout << "accept: melting" << endl;)
} else
} else {
#ifdef NO_VIOLATIONS
if (newscore < bestscore) {
accepttrans = true;
......@@ -815,6 +818,23 @@ void anneal(bool scoring_selftest, double scale_neighborhood,
<< ")" << endl;)
}
#else
#ifdef SPECIAL_VIOLATION_TREATMENT
/*
* In this ifdef, we always accept new solutions that have fewer
* violations than the old solution, and when we're trying to
* determine whether or not to accept a new solution with a higher
* score, we don't take violations into the account.
*
* The problem with this shows up at low temperatures. What can often
* happen is that we accept a solution with worse violations but a
* better (or similar) score. Then, if we were to try, say the first
* solution (or a score-equivalent one) again, we'd accept it again.
*
* What this leads to is 'thrashing', where we have a whole lot of
* variation of scores over time, but are not making any real
* progress. This prevents the cooling schedule from converging for
* much, much longer than it should really take.
*/
if ((violated == bestviolated) && (newscore < bestscore)) {
accepttrans = true;
RDEBUG(cout << "accept: better (" << newscore << "," << bestscore
......@@ -832,6 +852,31 @@ void anneal(bool scoring_selftest, double scale_neighborhood,
<< bestscore << "," << expf(scorediff/(temp*sensitivity))
<< ")" << endl;)
}
#else // no SPECIAL_VIOLATION_TREATMENT
/*
* In this branch of the ifdef, we give violations no special
* treatment when it comes to accepting new solution - we just add
* them into the score. This makes assign behave in a more 'classic'
* simulated annealing manner.
*
* One consequence, though, is that we have to be more careful with
* scores. We do not want to be able to get into a situation where
* adding a violation results in a _lower_ score than a solution with
* fewer violations.
*/
double adjusted_new_score = newscore + violated * VIOLATION_SCORE;
double adjusted_old_score = bestscore + bestviolated *
VIOLATION_SCORE;
if (adjusted_new_score < adjusted_old_score) {
accepttrans = true;
} else if (accept(adjusted_old_score - adjusted_new_score,temp)) {
accepttrans = true;
}
#endif // SPECIAL_VIOLATION_TREATMENT
}
#endif
if (accepttrans) {
......@@ -985,11 +1030,9 @@ NOTQUITEDONE:
#endif
#endif
// Revert to best found so far - do link/lan migration as well
#ifdef SCORE_DEBUG
cerr << "Reverting to best known solution." << endl;
#endif
RDEBUG(
printf("temp_end: temp: %f ratio: %f stddev: %f\n",temp,temp * avgscore / initialavg,stddev);
);
// Add this to the history, and computed a smoothed average
smoothedavg = avgscore / (nhist + 1);
......@@ -1020,7 +1063,7 @@ NOTQUITEDONE:
printf("avgs: real: %f, smoothed %f, initial: %f\n",avgscore,smoothedavg,initialavg);
printf("epsilon: (%f) %f / %f * %f / %f < %f (%f)\n", fabs(deltaavg), temp, initialavg,
deltaavg, deltatemp, epsilon,(temp / initialavg) * (deltaavg/ deltatemp));
)
);
if ((tsteps >= mintsteps) &&
#ifdef ALLOW_NEGATIVE_DELTA
((fabs(deltaavg) < 0.0000001)
......
......@@ -116,6 +116,9 @@ static float LINK_RESOLVE_DIRECT = 4.0;
static float LINK_RESOLVE_INTRASWITCH = 2.0;
static float LINK_RESOLVE_INTERSWITCH = 1.0;
// The amount that each violation contributes to the total score
static float VIOLATION_SCORE = 1.0;
static struct config_param options[] = {
{ "IT", CONFIG_INT, &init_temp, 0 },
{ "OP", CONFIG_INT, &USE_OPTIMAL, 0 },
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment