autotuner.cpp 2 KB
Newer Older
Luka Stanisic's avatar
Luka Stanisic committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126
#include "autotuner.h"

void Autotuner::Reset()
{
  stopTuning = false;
  workload = 100;

  best_time = 0.;
  best_workload = 0;

  a = 1;
  b = 50;
  c = 100;
  x = 50;
  limit = 1;
  fb = 0.;
  fx = 0.;

  if (algo == 3) workload = 50;
}

bool Autotuner::Needed(int iteration)
{
  if (stopTuning) return false;

  switch (algo)
    {
    case 1:
    case 3:
      return iteration % (stable + 1) == stable;
    case 2: return (iteration == (int) stable / 2 ) || (iteration == stable);
    default: /* Should never happen */;
    }
  return false;
}

bool Autotuner::Finished()
{
  switch (algo)
    {
    case 1:
      if (workload < 30)
	{
	  workload = best_workload;
	  return stopTuning = true;
	}
      break;
    case 2:
      if (best_workload != 0) return stopTuning = true;
      break;
    case 3:
      if ((c - b == limit) && (b - a == limit)) return stopTuning = true;
      break;
    default: /* Should never happen */;
    }
  return false;
}

void Autotuner::Tune(double compTime)
{
  switch (algo)
    {
    case 1: AlgoSimple(compTime); break;
    case 2: AlgoRatio(compTime); break;
    case 3: AlgoBisection(compTime); break;
    default: /* Should never happen */;
    }
}

void Autotuner::AlgoSimple(double compTime)
{
  if (best_time == 0. || compTime < best_time)
    {
      best_time = compTime;
      best_workload = workload;
    }

  workload -= 5;
}

void Autotuner::AlgoRatio(double compTime)
{
  if (best_time == 0.)
    {
      best_time = compTime;
      workload = 1;
    }
  else
    {
      best_workload = (int) 100 * (compTime / (best_time + compTime));
      workload = best_workload;
    }
}

void Autotuner::AlgoBisection(double compTime)
{
  if (fb == 0.)
    {
      fb = compTime;
      x = 75;
      workload = x;
      return;
    }

  fx = compTime;

  if (fx < fb)
    {
      if (x < b)
	c = b;
      else
	a = b;
      b = x;
      fb = fx;
    }
  else
    {
      if (x < b)
	a = x;
      else
	c = x;
    }

  x = (c-b > b-a) ? (int)(b+(c-b)/2) : (int)(a+(b-a+1)/2);
  workload = x;
}