Update CoreClr, PgoData to preview1-26004-01, master-20171204-0047, respectively...
[platform/upstream/coreclr.git] / tests / src / JIT / Performance / CodeQuality / BenchF / FFT / FFT.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 // FFT benchmark adapted from a Fortran routine from the book
6 // Digital Signal Analysis, Samuel Stearns, Hayden Book Co.
7
8 using Microsoft.Xunit.Performance;
9 using System;
10 using System.Runtime.CompilerServices;
11 using Xunit;
12
13 [assembly: OptimizeForBenchmarks]
14
15 namespace Benchstone.BenchF
16 {
17 public static class FFT
18 {
19 #if DEBUG
20     public const int Iterations = 1;
21 #else
22     public const int Iterations = 300000;
23 #endif
24
25     private static readonly int s_points = 16;
26     public static volatile object VolatileObject;
27
28     [MethodImpl(MethodImplOptions.NoInlining)]
29     private static void Escape(object obj)
30     {
31         VolatileObject = obj;
32     }
33
34     [MethodImpl(MethodImplOptions.NoInlining)]
35     private static bool Bench()
36     {
37         double[] fr = new double[17];
38         double[] fi = new double[17];
39
40         int i;
41         double t;
42
43         for (int iter = 1; iter <= Iterations; iter++)
44         {
45             for (i = 1; i <= s_points; ++i)
46             {
47                 t = ((double)0.375) * ((double)(i - 1));
48                 fr[i] = System.Math.Exp(-t) * System.Math.Sin(t);
49                 fi[i] = 0.0;
50             }
51             FastFourierT(fr, fi, s_points);
52         }
53
54         // Escape the results to live-out.
55         Escape(fr);
56         Escape(fi);
57
58         return true;
59     }
60
61     private static void FastFourierT(double[] fr, double[] fi, int n)
62     {
63         int i, j, l, m;
64         int istep, mr, nn;
65         double a, el, tr, ti, wr, wi;
66
67         mr = 0;
68         nn = n - 1;
69         m = 1;
70
71         do
72         {
73             l = n;
74             for (l = l / 2; ((mr + l) > nn); l = l / 2)
75             {
76             }
77             // l <= n/2
78             // mr <= (mr % l) + l ==> mr <= (l - 1) + l = 2l - 1
79             // ==> mr <= n - 1
80             mr = (mr % l) + l;
81
82             if (mr > m)
83             {
84                 // Accessing upto m + 1 ==> nn + 1 ==> n - 1 + 1 ==> n
85                 tr = fr[m + 1];
86                 // Accessing upto mr + 1 ==> n - 1 + 1 ==> n
87                 fr[m + 1] = fr[mr + 1];
88                 fr[mr + 1] = tr;
89                 ti = fi[m + 1];
90                 fi[m + 1] = fi[mr + 1];
91                 fi[mr + 1] = ti;
92             }
93             ++m;
94         } while (m <= nn);
95
96         for (l = 1; l < n; l = istep)
97         {
98             istep = 2 * l;
99
100             el = ((double)l);
101             m = 1;
102             do
103             {
104                 a = ((double)3.1415926535) * (((double)(1 - m)) / el);
105                 wr = System.Math.Cos(a);
106                 wi = System.Math.Sin(a);
107                 i = m;
108                 do
109                 {
110                     // l can have a maximum value of 2^x where 2^x < n and 2^(x+1) = n, since n is even
111                     // ==> istep <= 2^(x+1) ==> i can only take the value of m and m <= l
112                     // Therefore, j <= l + l
113                     // or j <= 2^x + 2^x = 2^(x+1) = n
114                     // i.e. j <= n
115                     j = i + l;
116
117                     // Accessing upto j <= n, i <= n
118                     tr = wr * fr[j] - wi * fi[j];
119                     ti = wr * fi[j] + wi * fr[j];
120                     fr[j] = fr[i] - tr;
121                     fi[j] = fi[i] - ti;
122                     fr[i] = fr[i] + tr;
123                     fi[i] = fi[i] + ti;
124                     i += istep;
125                 } while (i <= n);
126                 ++m;
127             } while (m <= l);
128         }
129     }
130
131     [Benchmark]
132     public static void Test()
133     {
134         foreach (var iteration in Benchmark.Iterations)
135         {
136             using (iteration.StartMeasurement())
137             {
138                 Bench();
139             }
140         }
141     }
142
143     private static bool TestBase()
144     {
145         bool result = Bench();
146         return result;
147     }
148
149     public static int Main()
150     {
151         bool result = TestBase();
152         return (result ? 100 : -1);
153     }
154 }
155 }