// Jason Winnebeck, v1, 12/9/98
// This program is freeware
// Example program showing speed differences between fix class and float

//Libraries needed:
// allegro v3.0+WIP (Nov 25)

//This profiles the allegro fix class to the float class, using common
// functions that would be used.  You can also learn from this program the
// affect of the optimization flags for GCC, and etc, to see the time
// effects

//RESULTS ON A P200MMX, 32 MEG RAM, RUNNING IN WIN95
//Runs calculations 100,000 times each
//Accurate to .005  (5 ms)
//gcc -WALL
// Float: .585
// Fixed: .495
//gcc -s -o2
// Float: .075
// Fixed: .070
//gcc -s -o3 -m486
// Float: .070
// Fixed: .070
//gcc -s -o3 -m486 -fomit-frame-pointer -ffast-math
// Float: .070
// Fixed: .070
//gcc -s -o3 -mpentium -fomit-frame-pointer -ffast-math
// Float: .070
// Fixed: .070
//gcc -m486
// Float: .585
// Fixed: .495

//NEW DATA!!!  Using fixed instead of fix(class ver)
//gcc -WALL
// Float: .570
// Fixed: .210
//gcc -s -o3 -m486 -fomit-frame-pointer -ffast-math
// Float: .070
// Fixed: .020

//data as of 3/25/00 -- PIII 500 under Win98SE DOS box, 100k calcs
//gcc -s -m486 -fomit-frame-pointer -ffast-math
// Float : .130-.135
// Double: .125-.135
// Fixed : .060
// Float was almost always slower but a little
//gcc -s -o3 -m486 -fomit-frame-pointer -ffast-math
// Float : .030-.035
// Double: .030-.035
// Fixed : .005 or less??? (.005 is lowest measurable)

//MSVC++ 6 Enterprise, 3/25/00, same specs as above, console app, debug
// Float : .345
// Double: .345-.360
// Fixed : .070
//now in release compile (optimized):
// Float : .065-.075
// Double: .005-.010
// Fixed : .010-.015

//CONCLUSIONS:
//In a pentium using optimization, float and fix seem equal.  None of the
// other parameters seem to affect anything on this scale

//However, later results show that the results are slowed by implimentation
// of the fix class over the fixed typedef. (2x to 3x increase in speed!!!)

//Comparisons done on a double and float on a PIII show no relevant decrease
//in speed.  Fixed calculations are still much faster.

#define USE_CONSOLE
#include <allegro.h>
#include <iostream.h>
#include <iomanip.h>
#include <conio.h>

volatile unsigned int tme;
#ifdef ALLEGRO_GCC
void inc_tme(...) {
#else
void inc_tme() {
#endif
  tme++;
}
END_OF_FUNCTION(inc_tme);

void StartTimer() {
  tme = 0;
  install_int(inc_tme, 5);
}

float GetTime() { //returns time in seconds
  remove_int(inc_tme);
  return tme / 200.0;
}

void DisplayTime(const char *str) {
  float temp = GetTime();
  cout << setprecision(3) << setiosflags(ios::fixed);
  cout << str << temp << endl;
}

int main() {
  //clrscr();

  allegro_init();
  install_timer();
  install_keyboard();

  LOCK_VARIABLE(tme);
  LOCK_FUNCTION(inc_tme);

  cout << "Timing floating point functions" << endl;
  cout << "  (assign, copy, sqrt, sin, cos, atan2, mult, div, add, sub, int->float, float->int, ++): " << endl;
  int temp, c;
  float ftest;
  float ftest2;
  StartTimer();
  for (c=0; c<100000; c++) {
    ftest = 5.5;
    ftest2 = ftest;
    ftest = sqrt(ftest2);
    ftest = sin(ftest2);
    ftest = cos(ftest2);
    ftest *= ftest2;
    ftest /= ftest2;
    ftest += ftest2;
    ftest -= ftest2;
    ftest = c;
    temp = int(ftest);
    ftest2++;
  }
  DisplayTime("Floating Point Time: ");

  cout << "Timing floating point functions (double)" << endl;
  cout << "  (assign, copy, sqrt, sin, cos, atan2, mult, div, add, sub, int->float, float->int, ++): " << endl;
  double dtest;
  float dtest2;
  StartTimer();
  for (c=0; c<100000; c++) {
    dtest = 5.5;
    dtest2 = dtest;
    dtest = sqrt(dtest2);
    dtest = sin(dtest2);
    dtest = cos(dtest2);
    dtest *= dtest2;
    dtest /= dtest2;
    dtest += dtest2;
    dtest -= dtest2;
    dtest = c;
    temp = int(dtest);
    dtest2++;
  }
  DisplayTime("Floating Point Time: ");
//Keep in mind only the fixed or fix class can be used at a time, not both,
// so this is remmed out!
/*
  cout << "Timing fix class functions" << endl;
  cout << "  (assign, copy, sqrt, sin, cos, atan2, mult, div, add, sub, int->float, float->int, ++): " << endl;
  fix t;
  fix t2;
  StartTimer();
  for (c=0; c<100000; c++) {
    t = 5.5;
    t2 = t;
    t = sqrt(t2);
    t = sin(t2);
    t = cos(t2);
    t *= t2;
    t /= t2;
    t += t2;
    t -= t2;
    t = c;
    temp = int(t);
    t2++;
  }
  DisplayTime("Fixed Class Time: ");
*/
  cout << "Timing fixed point functions" << endl;
  cout << "  (assign, copy, sqrt, sin, cos, mult, div, add, sub, int->float, float->int, ++): " << endl;
  fixed t;
  fixed t2;
  StartTimer();
  for (c=0; c<100000; c++) {
    t = ftofix(5.5);
    t2 = t;
    t = fsqrt(t2);
    t = fsin(t2);
    t = fcos(t2);
    t = fmul(t, t2);
    t = fdiv(t, t2);
    t = fadd(t, t2);
    t += t2;
    t -= t2;
    t = c;
    temp = fixtoi(t);
    t2 = t2 + fixtoi(1);
  }
  DisplayTime("Fixed Point Time: ");

  cout << "Done Testing!!!" << endl;
  cout << " Press a key..." << endl;
  readkey();

  allegro_exit();
  return 0;
}
