public static void Main(string[] args) { // demo(); Console.Write("Denominator: "); long div = long.Parse(Console.ReadLine()); Console.Write("Max enumerator: "); long max = long.Parse(Console.ReadLine()); long mul; int shift; if (Optimize.FindMulShift(max, div, out mul, out shift)) { string msg = " n / " + div.ToString() + "\t <==> n * " + mul.ToString() + " >> " + shift.ToString(); System.Console.WriteLine(msg); } else { System.Console.WriteLine(div.ToString() + " not found"); } System.Console.ReadLine(); }
public static void demo() { long mul = 0; int shift = 0; long div = 0; long max = 0; int high = 1000; int maxdiv = 100; int iterations = 1000; // some doubles to average timing double avg = 0; double s1; double s2; HiPerfTimer pt = new HiPerfTimer(); #region example I pt.Start(); for (div = 1; div < 100; div++) { max = 1000; // 1L<<30; // = 2^30 if (Optimize.FindMulShift(max, div, out mul, out shift)) { string msg = " / " + div.ToString() + "\t <==> * " + mul.ToString() + " >> " + shift.ToString(); System.Console.WriteLine(msg); } else { System.Console.WriteLine(div.ToString() + " not found"); System.Console.ReadLine(); } } pt.Stop(); System.Console.WriteLine("done, " + pt.Duration().ToString("0.00")); System.Console.ReadLine(); #endregion #region performance measurement / // // How much faster is it? // avg = 0; System.Console.WriteLine("start / "); for (div = -maxdiv; div <= maxdiv; div++) { if (div == 0) { continue; } Optimize.FindMulShift(high, div, out mul, out shift); // normal div timing, pt.Start(); long x = 0; for (int i = 0; i < iterations; i++) { for (int j = -high; j < high; j++) { x = j / div; } } pt.Stop(); s1 = pt.Duration(); // mul shift timing, // with fixed dividers, the if then else construct will be simpler!! // just as example how to handle negative dividers pt.Start(); for (int i = 0; i < iterations; i++) { for (int j = -high; j < high; j++) { if (j >= 0) { if (div > 0) { x = ((j * mul) >> shift); } else { x = -((j * mul) >> shift); } } else { if (div > 0) { x = -((-j * mul) >> shift); } else { x = ((-j * mul) >> shift); } } } } pt.Stop(); s2 = pt.Duration(); double d = 100 - 100 * s2 / s1; System.Console.WriteLine(div + "\t" + s1.ToString("0.000") + "\t" + s2.ToString("0.000") + "\tperc: " + d.ToString("0.00")); avg += d; } // TODO: remove hard coded average System.Console.WriteLine("average: " + (avg / maxdiv / 2).ToString("0.00")); System.Console.WriteLine("done"); System.Console.ReadLine(); #endregion #region performance measurement % // // How much faster is it? // avg = 0; System.Console.WriteLine("start %"); for (div = -maxdiv; div <= maxdiv; div++) { if (div == 0) { continue; } Optimize.FindMulShift(high, div, out mul, out shift); // normal div timing, pt.Start(); long x = 0; for (int i = 0; i < iterations; i++) { for (int j = -high; j < high; j++) { x = j % div; } } pt.Stop(); s1 = pt.Duration(); // mul shift timing, // with fixed dividers, the if then else construct will be simpler!! pt.Start(); for (int i = 0; i < iterations; i++) { //long y = 0; for (int j = -high; j < high; j++) { if (j >= 0) { if (div > 0) { x = j - ((j * mul) >> shift) * div; } else { x = j - ((j * mul) >> shift) * -div; } } else { if (div > 0) { x = j + ((-j * mul) >> shift) * div; } else { x = j + ((-j * mul) >> shift) * (-div); } } // if (x != j%div) // { // Console.WriteLine(j + " " + div + " "+ x + " " + y); // } } } pt.Stop(); s2 = pt.Duration(); double d = 100 - 100 * s2 / s1; System.Console.WriteLine(div + "\t" + s1.ToString("0.000") + "\t" + s2.ToString("0.000") + "\tperc: " + d.ToString("0.00")); avg += d; } System.Console.WriteLine("average: " + (avg / maxdiv / 2).ToString("0.00")); System.Console.WriteLine("done"); System.Console.ReadLine(); #endregion #region performance measurement / (positive only) // // How much faster is it? // avg = 0; System.Console.WriteLine("start / (only positive values)"); for (div = 1; div <= maxdiv; div++) { if (div == 0) { continue; // allows div to start with -maxdiv } Optimize.FindMulShift(high, div, out mul, out shift); // normal div timing, pt.Start(); long x = 0; for (int i = 0; i < iterations; i++) { for (int j = 0; j < high; j++) { x = j / div; } } pt.Stop(); s1 = pt.Duration(); // mul shift timing, // with fixed dividers, the if then else construct will be simpler!! pt.Start(); for (int i = 0; i < iterations; i++) { for (int j = 0; j < high; j++) { x = ((j * mul) >> shift); } } pt.Stop(); s2 = pt.Duration(); // calculate gain double d = 100 - 100 * s2 / s1; System.Console.WriteLine(div + "\t" + s1.ToString("0.000") + "\t" + s2.ToString("0.000") + "\tperc: " + d.ToString("0.00")); avg += d; } System.Console.WriteLine("average: " + (avg / maxdiv).ToString("0.00")); System.Console.WriteLine("done"); System.Console.ReadLine(); #endregion } // Main