1  using System;


2  using System.Threading;


3  using System.Threading.Tasks;


4  using HeuristicLab.Common;


5  using HeuristicLab.Core;


6  using HeuristicLab.Data;


7  using HeuristicLab.Optimization;


8  using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;


9 


10  namespace HeuristicLab.Algorithms.Benchmarks {


11  [Item("Whetstone Algorithm", "A Whetstone benchmark algorithm.")]


12  [Creatable("Benchmarks")]


13  [StorableClass]


14  public class Whetstone : Algorithm {


15  private DateTime lastUpdateTime;


16 


17  [Storable]


18  private ResultCollection results;


19 


20  #region Benchmark Fields


21 


22  private long begin_time;


23  private long end_time;


24  //private long total_time;


25 


26  private int ITERATIONS;


27  private int numberOfCycles;


28  private int cycleNo;


29  private double x1, x2, x3, x4, x, y, t, t1, t2;


30  private double[] z = new double[1];


31  private double[] e1 = new double[4];


32  private int i, j, k, l, n1, n2, n3, n4, n6, n7, n8, n9, n10, n11;


33 


34  #endregion


35 


36  #region Properties


37 


38  public override ResultCollection Results {


39  get { return results; }


40  }


41 


42  #endregion


43 


44  #region Costructors


45 


46  public Whetstone()


47  : base() {


48  results = new ResultCollection();


49  }


50 


51  private Whetstone(Whetstone original, Cloner cloner)


52  : base(original, cloner) {


53  results = new ResultCollection();


54  }


55 


56  #endregion


57 


58  public override IDeepCloneable Clone(Cloner cloner) {


59  return new Whetstone(this, cloner);


60  }


61 


62  public override void Prepare() {


63  results.Clear();


64  OnPrepared();


65  }


66 


67  public override void Start() {


68  var cancellationTokenSource = new CancellationTokenSource();


69  OnStarted();


70  Task task = Task.Factory.StartNew(Run, cancellationTokenSource.Token, cancellationTokenSource.Token);


71  task.ContinueWith(t => {


72  try {


73  t.Wait();


74  }


75  catch (AggregateException ex) {


76  try {


77  ex.Flatten().Handle(x => x is OperationCanceledException);


78  }


79  catch (AggregateException remaining) {


80  if (remaining.InnerExceptions.Count == 1) OnExceptionOccurred(remaining.InnerExceptions[0]);


81  else OnExceptionOccurred(remaining);


82  }


83  }


84  cancellationTokenSource.Dispose();


85  cancellationTokenSource = null;


86  OnStopped();


87  });


88  }


89 


90  private void Run(object state) {


91  CancellationToken cancellationToken = (CancellationToken)state;


92  lastUpdateTime = DateTime.Now;


93  System.Timers.Timer timer = new System.Timers.Timer(250);


94  timer.AutoReset = true;


95  timer.Elapsed += new System.Timers.ElapsedEventHandler(timer_Elapsed);


96  timer.Start();


97  try {


98  RunBenchmark();


99  }


100  finally {


101  timer.Elapsed = new System.Timers.ElapsedEventHandler(timer_Elapsed);


102  timer.Stop();


103  ExecutionTime += DateTime.Now  lastUpdateTime;


104  }


105 


106  cancellationToken.ThrowIfCancellationRequested();


107  }


108 


109  private void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) {


110  System.Timers.Timer timer = (System.Timers.Timer)sender;


111  timer.Enabled = false;


112  DateTime now = DateTime.Now;


113  ExecutionTime += now  lastUpdateTime;


114  lastUpdateTime = now;


115  timer.Enabled = true;


116  }


117 


118  #region Whetstone Benchmark


119 


120  private void RunBenchmark() {


121  ITERATIONS = 100; // ITERATIONS / 10 = Millions Whetstone instructions


122 


123  numberOfCycles = 100;


124  int numberOfRuns = 10;


125  float elapsedTime = 0;


126  float meanTime = 0;


127  float rating = 0;


128  float meanRating = 0;


129  int intRating = 0;


130 


131  for (int runNumber = 1; runNumber <= numberOfRuns; runNumber++) {


132  //System.Console.WriteLine(runNumber + ". Test");


133  elapsedTime = (float)(MainCalc() / 1000);


134  meanTime = meanTime + (elapsedTime * 1000 / numberOfCycles);


135  rating = (1000 * numberOfCycles) / elapsedTime;


136  meanRating = meanRating + rating;


137  intRating = (int)rating;


138  numberOfCycles += 10;


139  }


140 


141  meanTime = meanTime / numberOfRuns;


142  meanRating = meanRating / numberOfRuns;


143  intRating = (int)meanRating;


144  //System.Console.WriteLine("Number of Runs " + numberOfRuns);


145  //System.Console.WriteLine("Average time per cycle " + meanTime + " ms.");


146  //System.Console.WriteLine("Average Whetstone Rating " + intRating + " KWIPS");


147  //Results.Add(new Result("KWIPS", new IntValue(intRating)));


148  Results.Add(new Result("MWIPS", new IntValue(intRating / 1000)));


149  }


150 


151  private double MainCalc() {


152  // initialize constants


153  t = 0.499975;


154  t1 = 0.50025;


155  t2 = 2.0;


156 


157  // set values of module weights


158  n1 = 0 * ITERATIONS;


159  n2 = 12 * ITERATIONS;


160  n3 = 14 * ITERATIONS;


161  n4 = 345 * ITERATIONS;


162  n6 = 210 * ITERATIONS;


163  n7 = 32 * ITERATIONS;


164  n8 = 899 * ITERATIONS;


165  n9 = 616 * ITERATIONS;


166  n10 = 0 * ITERATIONS;


167  n11 = 93 * ITERATIONS;


168 


169  begin_time = DateTime.Now.Ticks / 10000; // get ms


170 


171  for (cycleNo = 1; cycleNo <= numberOfCycles; cycleNo++) {


172  /* MODULE 1: simple identifiers */


173  x1 = 1.0;


174  x2 = x3 = x4 = 1.0;


175  for (i = 1; i <= n1; i += 1) {


176  x1 = (x1 + x2 + x3  x4) * t;


177  x2 = (x1 + x2  x3 + x4) * t; // correction: x2 = ( x1 + x2  x3  x4 ) * t;


178  x3 = (x1  x2 + x3 + x4) * t; // correction: x3 = ( x1  x2 + x3 + x4 ) * t;


179  x4 = (x1 + x2 + x3 + x4) * t;


180  }


181 


182  /* MODULE 2: array elements */


183  e1[0] = 1.0;


184  e1[1] = e1[2] = e1[3] = 1.0;


185  for (i = 1; i <= n2; i += 1) {


186  e1[0] = (e1[0] + e1[1] + e1[2]  e1[3]) * t;


187  e1[1] = (e1[0] + e1[1]  e1[2] + e1[3]) * t;


188  e1[2] = (e1[0]  e1[1] + e1[2] + e1[3]) * t;


189  e1[3] = (e1[0] + e1[1] + e1[2] + e1[3]) * t;


190  }


191 


192  /* MODULE 3: array as parameter */


193  for (i = 1; i <= n3; i += 1)


194  pa(e1);


195 


196  /* MODULE 4: conditional jumps */


197  j = 1;


198  for (i = 1; i <= n4; i += 1) {


199  if (j == 1)


200  j = 2;


201  else


202  j = 3;


203  if (j > 2)


204  j = 0;


205  else


206  j = 1;


207  if (j < 1)


208  j = 1;


209  else


210  j = 0;


211  }


212 


213  /* MODULE 5: omitted */


214 


215  /* MODULE 6: integer arithmetic */


216  j = 1;


217  k = 2;


218  l = 3;


219  for (i = 1; i <= n6; i += 1) {


220  j = j * (k  j) * (l  k);


221  k = l * k  (l  j) * k;


222  l = (l  k) * (k + j);


223  e1[l  2] = j + k + l; /* C arrays are zero based */


224  e1[k  2] = j * k * l;


225  }


226 


227  /* MODULE 7: trig. functions */


228  x = y = 0.5;


229  for (i = 1; i <= n7; i += 1) {


230  x = t * Math.Atan(t2 * Math.Sin(x) * Math.Cos(x) / (Math.Cos(x + y) + Math.Cos(x  y)  1.0));


231  y = t * Math.Atan(t2 * Math.Sin(y) * Math.Cos(y) / (Math.Cos(x + y) + Math.Cos(x  y)  1.0));


232  }


233 


234  /* MODULE 8: procedure calls */


235  x = y = z[0] = 1.0;


236  for (i = 1; i <= n8; i += 1)


237  p3(x, y, z);


238 


239  /* MODULE9: array references */


240  j = 0;


241  k = 1;


242  l = 2;


243  e1[0] = 1.0;


244  e1[1] = 2.0;


245  e1[2] = 3.0;


246  for (i = 1; i <= n9; i++)


247  p0();


248 


249  /* MODULE10: integer arithmetic */


250  j = 2;


251  k = 3;


252  for (i = 1; i <= n10; i += 1) {


253  j = j + k;


254  k = j + k;


255  j = k  j;


256  k = k  j  j;


257  }


258 


259  /* MODULE11: standard functions */


260  x = 0.75;


261  for (i = 1; i <= n11; i += 1)


262  x = Math.Sqrt(Math.Exp(Math.Log(x) / t1));


263  } /* for */


264 


265  end_time = DateTime.Now.Ticks / 10000; // get ms


266  //System.Console.WriteLine(" (time for " + numberOfCycles + " cycles): " + (end_time  begin_time) + " millisec.");


267 


268  return (end_time  begin_time);


269  }


270 


271  public void pa(double[] e) {


272  int j;


273  j = 0;


274  do {


275  e[0] = (e[0] + e[1] + e[2]  e[3]) * t;


276  e[1] = (e[0] + e[1]  e[2] + e[3]) * t;


277  e[2] = (e[0]  e[1] + e[2] + e[3]) * t;


278  e[3] = (e[0] + e[1] + e[2] + e[3]) / t2;


279  j += 1;


280  }


281  while (j < 6);


282  }


283 


284  public void p3(double x, double y, double[] z) {


285  x = t * (x + y);


286  y = t * (x + y);


287  z[0] = (x + y) / t2;


288  }


289 


290  public void p0() {


291  e1[j] = e1[k];


292  e1[k] = e1[l];


293  e1[l] = e1[j];


294  }


295 


296  #endregion


297  }


298  }

