Пример #1
0
static int
worst_cost (const struct predicate *p)
{
  if (p)
    {
      unsigned int cost_r, cost_l, worst;
      cost_l = worst_cost (p->pred_left);
      cost_r = worst_cost (p->pred_right);
      worst = (cost_l > cost_r) ? cost_l : cost_r;
      if (worst < p->p_cost)
	worst = p->p_cost;
      return worst;
    }
  else
    {
      return 0;
    }
}
Пример #2
0
MyAlgorithm::MyAlgorithm(const Problem& pbm, const SetUpParams& setup):
    _pbm(pbm), _setup(setup)
{
    initialize();
    evaluate();
    _upper_cost = best_cost();
    _lower_cost = worst_cost();
    mixrate = 1;
}
Пример #3
0
/* Consider swapping p->pred_left->pred_right with p->pred_right,
 * if that yields a faster evaluation.   Normally the left predicate is
 * evaluated first.
 *
 * If the operation is an OR, we want the left predicate to be the one that
 * succeeds most often.   If it is an AND, we want it to be the predicate that
 * fails most often.
 *
 * We don't consider swapping arms of an operator where their cost is
 * different or where they have side effects.
 *
 * A viable test case for this is
 * ./find -D opt   -O3  .   \! -type f -o -type d
 * Here, the ! -type f should be evaluated first,
 * as we assume that 95% of inodes are vanilla files.
 */
static bool
consider_arm_swap (struct predicate *p)
{
  int left_cost, right_cost;
  const char *reason = NULL;
  struct predicate **pl, **pr;

  if (BI_OP != p->p_type)
    reason = "Not a binary operation";

  if (!reason)
    {
      if (NULL == p->pred_left || NULL == p->pred_right)
	reason = "Doesn't have two arms";
    }


  if (!reason)
    {
      if (NULL == p->pred_left->pred_right)
	reason = "Left arm has no child on RHS";
    }
  pr = &p->pred_right;
  pl = &p->pred_left->pred_right;

  if (!reason)
    {
      if (subtree_has_side_effects (*pl))
	reason = "Left subtree has side-effects";
    }
  if (!reason)
    {
      if (subtree_has_side_effects (*pr))
	reason = "Right subtree has side-effects";
    }

  if (!reason)
    {
      left_cost = worst_cost (*pl);
      right_cost = worst_cost (*pr);

      if (left_cost < right_cost)
	{
	  reason = "efficient as-is";
	}
    }
  if (!reason)
    {
      bool want_swap;

      if (left_cost == right_cost)
	{
	  /* it's a candidate */
	  float succ_rate_l = (*pl)->est_success_rate;
	  float succ_rate_r = (*pr)->est_success_rate;

	  if (options.debug_options & DebugTreeOpt)
	    {
	      fprintf (stderr, "Success rates: l=%f, r=%f\n", succ_rate_l, succ_rate_r);
	    }

	  if (pred_is (p, pred_or))
	    {
	      want_swap = succ_rate_r < succ_rate_l;
	      if (!want_swap)
		reason = "Operation is OR; right success rate >= left";
	    }
	  else if (pred_is (p, pred_and))
	    {
	      want_swap = succ_rate_r > succ_rate_l;
	      if (!want_swap)
		reason = "Operation is AND; right success rate <= left";
	    }
	  else
	    {
	      want_swap = false;
	      reason = "Not 'AND' or 'OR'";
	    }
	}
      else
	{
	  want_swap = true;
	}

      if (want_swap)
	{
	  if (options.debug_options & DebugTreeOpt)
	    {
	      fprintf (stderr, "Performing arm swap on:\n");
	      print_tree (stderr, p, 0);
	    }
	  perform_arm_swap (p);
	  return true;
	}
    }


  if (options.debug_options & DebugTreeOpt)
    {
      fprintf (stderr, "Not an arm swap candidate (%s):\n", reason);
      print_tree (stderr, p, 0);
    }
  return false;
}