Separate large perf benchmarks into their own legs (#15231)
[platform/upstream/coreclr.git] / tests / src / JIT / Performance / CodeQuality / Benchstones / BenchF / Regula / Regula.cs
1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
4 //
5 // The modified regula-falsi routine adapted from Conte and De Boor
6
7 using Microsoft.Xunit.Performance;
8 using System;
9 using System.Runtime.CompilerServices;
10 using Xunit;
11
12 [assembly: OptimizeForBenchmarks]
13
14 namespace Benchstone.BenchF
15 {
16 public static class Regula
17 {
18 #if DEBUG
19     public const int Iterations = 1;
20 #else
21     public const int Iterations = 4000000;
22 #endif
23
24     public static volatile object VolatileObject;
25
26     [MethodImpl(MethodImplOptions.NoInlining)]
27     private static void Escape(object obj)
28     {
29         VolatileObject = obj;
30     }
31
32     [MethodImpl(MethodImplOptions.NoInlining)]
33     private static bool Bench()
34     {
35         double error, fxi;
36         double a, b, xi;
37         int idbg, iflag;
38
39         iflag = 0;
40         idbg = 0;
41         xi = 0;
42         error = 0.0;
43         fxi = 0.0;
44
45         for (int i = 1; i <= Iterations; i++)
46         {
47             a = 1.0;
48             b = 2.0;
49             Inner(ref a, ref b, 0.0000001, 0.0000000001, 30, out iflag);
50             if (iflag > 2)
51             {
52                 goto L999;
53             }
54
55             xi = (a + b) / 2.0;
56             error = System.Math.Abs(b - a) / 2.0;
57             fxi = FG(xi);
58
59             if (idbg != 0)
60             {
61                 System.Console.WriteLine(" the root is  {0:E}", xi);
62                 System.Console.WriteLine(" plus/minus {0}\n", error);
63                 System.Console.WriteLine(" fg(root):= {0:E}\n", fxi);
64             }
65
66         L999:
67             {
68             }
69         }
70
71         // Escape iflag, xi, error, and fxi so that they appear live
72         Escape(iflag);
73         Escape(xi);
74         Escape(error);
75         Escape(fxi);
76
77         return true;
78     }
79
80     private static double FG(double x)
81     {
82         return (-1.0 - (x * (1.0 - (x * x))));
83     }
84
85     private static void Inner(ref double a, ref double b, double xtol, double ftol, int ntol, out int iflag)
86     {
87         double signfa, prevfw, fa, fb, fw, w;
88
89         iflag = 0;
90         fa = FG(a);
91         if (fa < 0.0)
92         {
93             signfa = -1.0;
94         }
95         else
96         {
97             signfa = 1.0;
98         }
99
100         fb = FG(b);
101         if (signfa * fb <= 0.0)
102         {
103             goto L5;
104         }
105
106         iflag = 3;
107         goto L99;
108
109     L5:
110         w = a;
111         fw = fa;
112         for (int i = 1; i <= ntol; i++)
113         {
114             if (System.Math.Abs(b - a) / 2.0 <= xtol)
115             {
116                 goto L99;
117             }
118             if (System.Math.Abs(fw) > ftol)
119             {
120                 goto L9;
121             }
122
123             a = w;
124             b = w;
125             iflag = 1;
126             goto L99;
127
128         L9:
129             w = (fa * b - fb * a) / (fa - fb);
130             if (fw < 0.0)
131             {
132                 prevfw = -1.0;
133             }
134             else
135             {
136                 prevfw = 1.0;
137             }
138             fw = FG(w);
139
140             if (signfa * fw < 0.0)
141             {
142                 goto L10;
143             }
144             a = w;
145             fa = fw;
146             if (fw * prevfw > 0.0)
147             {
148                 fb = fb / 2.0;
149             }
150             goto L20;
151
152         L10:
153             b = w;
154             fb = fw;
155             if (fw * prevfw > 0.0)
156             {
157                 fa = fa / 2.0;
158             }
159
160         L20:
161             {
162             }
163         }
164
165         iflag = 2;
166     L99:
167         {
168         }
169     }
170
171     [Benchmark]
172     public static void Test()
173     {
174         foreach (var iteration in Benchmark.Iterations)
175         {
176             using (iteration.StartMeasurement())
177             {
178                 Bench();
179             }
180         }
181     }
182
183     private static bool TestBase()
184     {
185         bool result = Bench();
186         return result;
187     }
188
189     public static int Main()
190     {
191         bool result = TestBase();
192         return (result ? 100 : -1);
193     }
194 }
195 }