GPU рдХреЗ рд▓рд┐рдП Math.Sin (рдбрдмрд▓) рдлрд╝рдВрдХреНрд╢рди

рдкреНрд░рд╕реНрддрд╛рд╡рдирд╛


рдореБрдЭреЗ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рд╕рдордп рдореЗрдВ рд╡реАрдбрд┐рдпреЛ рдХрд╛рд░реНрдб рдкреНрд░реЛрд╕реЗрд╕рд░ рдкрд░ рдмрдврд╝реА рд╕рдЯреАрдХрддрд╛ рдХреЗ рд╕рд╛рде рдЪрд╛рдк рдХреА рдЧрдгрдирд╛ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдереАред

рд▓реЗрдЦрдХ рдиреЗ рдорд╛рдирдХ рдлрд╝рдВрдХреНрд╢рди System.Math.Sin () (C #) рдХреЛ рдкрд╛рд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд▓рдХреНрд╖реНрдп рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдирд╣реАрдВ рдХрд┐рдпрд╛ рдФрд░ рдЙрд╕ рддрдХ рдирд╣реАрдВ рдкрд╣реБрдВрдЪрд╛ред

рдХрд╛рдо рдФрд░ рдореЗрд░реА рдкрд╕рдВрдж рдХрд╛ рдкрд░рд┐рдгрд╛рдо (рдЙрди рд▓реЛрдЧреЛрдВ рдХреЗ рд▓рд┐рдП рдЬреЛ рдкрдврд╝рдирд╛ рдирд╣реАрдВ рдЪрд╛рд╣рддреЗ):

рд╕рд┐рди_3 (рд░реЗрдб)
using System; class Math_d { const double PI025 = Math.PI / 4; /// <summary> 2^17 = 131072 (1 ),   10000 ( ),  2^21 = 22097152 (16 )   +-1 ( ) (  ) </summary> const int length_mem = 22097152; const int length_mem_M1 = length_mem - 1; /// <summary>    sin,    . </summary> static double[] mem_sin; /// <summary>    cos,    . </summary> static double[] mem_cos; /// <summary>  ,   sin,    . </summary> public static void Initialise() { Ini_Mem_Sin(); Ini_Mem_Cos(); } /// <summary>       Cos,   . </summary> /// <param name="rad"></param> public static double Sin_3(double rad) { double rad_025; int i; //    //if (rad < 0) { rad = -rad + Math.PI; } i = (int)(rad / PI025); //   rad_025 = rad - PI025 * i; //     ( ) i = i & 7; //      8 //    switch (i) { case 0: return Sin_Lerp(rad_025); case 1: return Cos_Lerp(PI025 - rad_025); case 2: return Cos_Lerp(rad_025); case 3: return Sin_Lerp(PI025 - rad_025); case 4: return -Sin_Lerp(rad_025); case 5: return -Cos_Lerp(PI025 - rad_025); case 6: return -Cos_Lerp(rad_025); case 7: return -Sin_Lerp(PI025 - rad_025); } return 0; } /// <summary>   sin    </summary> static void Ini_Mem_Sin() { double rad; mem_sin = new double[length_mem]; for (int i = 0; i < length_mem; i++) { rad = (i * PI025) / length_mem_M1; mem_sin[i] = Math.Sin(rad); } } /// <summary>   cos    </summary> static void Ini_Mem_Cos() { double rad; mem_cos = new double[length_mem]; for (int i = 0; i < length_mem; i++) { rad = (i * PI025) / length_mem_M1; mem_cos[i] = Math.Cos(rad); } } /// <summary>      sin  0  pi/4. </summary> /// <param name="rad">     0  pi/4. </param> static double Sin_Lerp(double rad) { int i_0; int i_1; double i_0d; double percent; double a; double b; double s; percent = rad / PI025; i_0d = percent * length_mem_M1; i_0 = (int)i_0d; i_1 = i_0 + 1; a = mem_sin[i_0]; b = mem_sin[i_1]; s = i_0d - i_0; return Lerp(a, b, s); } /// <summary>      cos  0  pi/4. </summary> /// <param name="rad">     0  pi/4. </param> static double Cos_Lerp(double rad) { int i_0; int i_1; double i_0d; double percent; double a; double b; double s; percent = rad / PI025; i_0d = percent * length_mem_M1; i_0 = (int)i_0d; i_1 = i_0 + 1; a = mem_cos[i_0]; b = mem_cos[i_1]; s = i_0d - i_0; return Lerp(a, b, s); } /// <summary>      . (return a + s * (b - a)) </summary> /// <param name="a">  . </param> /// <param name="b">  . </param> /// <param name="s">  . 0 = a, 1 = b, 0.5 =   a  b. </param> public static double Lerp(double a, double b, double s) { return a + s * (b - a); } } 


рдкреНрд░рдХрд╛рд╢рди рдХреЗ рдХрд╛рд░рдг


  • рдПрдЪрдПрд▓рдПрд╕рдПрд▓ рднрд╛рд╖рд╛ рдореЗрдВ рджреЛрд╣рд░реЗ рдХреЗ рд▓рд┐рдП рдХреЛрдИ рдорд╛рдирдХ рдкрд╛рдк рдХрд╛рд░реНрдп рдирд╣реАрдВ рд╣реИ (рд▓реЗрдХрд┐рди рдпрд╣ рд╕рдЯреАрдХ рдирд╣реАрдВ рд╣реИ)
  • рдЗрд╕ рд╡рд┐рд╖рдп рдкрд░ рдЗрдВрдЯрд░рдиреЗрдЯ рдкрд░ рдмрд╣реБрдд рдХрдо рдЬрд╛рдирдХрд╛рд░реА рдЙрдкрд▓рдмреНрдз рд╣реИред

рдорд╛рдирд╛ рдЬрд╛рддрд╛ рд╣реИ



рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХрд┐рдпрд╛ рдЧрдпрд╛ рдкреИрд░рд╛рдореАрдЯрд░


  • Math.Sin рдХреЗ рд╕рд╛рде рд╕рдЯреАрдХрддрд╛
  • Math.Sin рдХреЗ рд╕рдВрдмрдВрдз рдореЗрдВ рдЧрддрд┐

рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХреЗ рдЕрд▓рд╛рд╡рд╛, рд╣рдо рдЙрдирдХреЗ рдкреНрд░рджрд░реНрд╢рди рдореЗрдВ рд╕реБрдзрд╛рд░ рдХрд░реЗрдВрдЧреЗред

рдЯреЗрд▓рд░ рд░реИрдВрдХ


рдкреЗрд╢реЗрд╡рд░реЛрдВ:

  • рдЙрдЪреНрдЪрддрдо рдкрд░рд┐рд╢реБрджреНрдзрддрд╛
    рдЗрд╕ рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдкрд╛рдк рдореВрд▓реНрдп рдХреА рдЧрдгрдирд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдХрд╛ рдЙрдкрдпреЛрдЧ рдЕрд╕реАрдо рд░реВрдк рд╕реЗ рд╕рдЯреАрдХ рдкрд╛рдк рдореВрд▓реНрдп рдХреА рдЧрдгрдирд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдЬрд┐рддрдиреЗ рдЕрдзрд┐рдХ рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐рдпреЛрдВ рд╕реЗ рдЧреБрдЬрд░рдирд╛ рдкрдбрд╝рддрд╛ рд╣реИ, рдЙрддрдирд╛ рд╣реА рд╕рд╣реА рдореВрд▓реНрдп рдЖрдЙрдЯрдкреБрдЯ рдкрд░ (рдПрдХ рдкрд░рд┐рдХрд▓реНрдкрдирд╛ рдореЗрдВ) рдкреНрд░рд╛рдкреНрдд рд╣реЛрддрд╛ рд╣реИред рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рдЕрднреНрдпрд╛рд╕ рдореЗрдВ, рдпрд╣ рдЙрдкрдпреЛрдЧ рдХрд┐рдП рдЬрд╛рдиреЗ рд╡рд╛рд▓реЗ рдорд╛рдкрджрдВрдбреЛрдВ рдХреЗ рдкреНрд░рдХрд╛рд░ (рдбрдмрд▓, рдлреНрд▓реЛрдЯ, рджрд╢рдорд▓рд╡, рдФрд░ рдЕрдиреНрдп) рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдЧрдгрдирд╛рдУрдВ рдХреА рд░рд╛рдЙрдВрдб-рдСрдл рддреНрд░реБрдЯрд┐рдпреЛрдВ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░рдиреЗ рдХреЗ рд▓рд╛рдпрдХ рд╣реИред
  • рдХрд┐рд╕реА рднреА рдХреЛрдг рдХреА рдЧрдгрдирд╛ рдХрд░рддрд╛ рд╣реИ
    рдЖрдк рдлрд╝рдВрдХреНрд╢рди рдХреЗ рддрд░реНрдХ рдХреЗ рд░реВрдк рдореЗрдВ рдХрд┐рд╕реА рднреА рдореВрд▓реНрдп рдХреЛ рджрд░реНрдЬ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП рдЗрдирдкреБрдЯ рдорд╛рдкрджрдВрдбреЛрдВ рдХреА рдирд┐рдЧрд░рд╛рдиреА рдХрд░рдиреЗ рдХреА рдХреЛрдИ рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИред
  • рд╕реНрд╡рддрдВрддреНрд░рддрд╛
    рдЗрд╕рдХреЗ рд▓рд┐рдП рдкреНрд░рд╛рд░рдВрднрд┐рдХ рдЧрдгрдирд╛ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ (рдЬреИрд╕рд╛ рдХрд┐ рдиреАрдЪреЗ рдЪрд░реНрдЪрд╛ рдХрд┐рдП рдЧрдП рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рдЕрдиреБрд╕рд╛рд░), рдФрд░ рдпрд╣ рдЕрдХреНрд╕рд░ рдЖрдзрд╛рд░ рд╣реЛрддрд╛ рд╣реИ рдЬрд┐рд╕ рдкрд░ рддреЗрдЬреА рд╕реЗ рдХрд╛рд░реНрдп рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВред

рд╡рд┐рдкрдХреНрд╖:

  • рдмрд╣реБрдд рдХрдо рдЧрддрд┐ (4-10%)
    рдореИрдереНрд╕ рдХреА рд╕рдЯреАрдХрддрд╛ рдХреЗ рдХрд░реАрдм рд╕рдЯреАрдХрддрд╛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдмрд╣реБрдд рд╕рд╛рд░реЗ рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐рдпреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдЗрд╕рдХреЗ рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк, рдпрд╣ рдорд╛рдирдХ рдлрд╝рдВрдХреНрд╢рди рдХреА рддреБрд▓рдирд╛ рдореЗрдВ 25 рдЧреБрдирд╛ рдзреАрдореА рдЧрддрд┐ рд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред
  • рдХреЛрдг рдЬрд┐рддрдирд╛ рдмрдбрд╝рд╛ рд╣реЛрдЧрд╛, рд╕рдЯреАрдХрддрд╛ рдЙрддрдиреА рд╣реА рдХрдо рд╣реЛрдЧреА
    рдлрдВрдХреНрд╢рди рдореЗрдВ рдЬрд┐рддрдирд╛ рдмрдбрд╝рд╛ рдХреЛрдг рдкреНрд░рд╡реЗрд╢ рдХрд░рддрд╛ рд╣реИ, рдЙрддрдирд╛ рд╣реА рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐рдпреЛрдВ рдХреЛ Math.Sin рдХреЗ рд╕рдорд╛рди рд╕рдЯреАрдХрддрд╛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред

рдореВрд▓ рд░реВрдк (рдЧрддрд┐: 4%):

рдорд╛рдирдХ рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ рдлреИрдХреНрдЯреЛрд░рд┐рдпрд▓ рдХреА рдЧрдгрдирд╛ рдХрд░рдирд╛ рд╢рд╛рдорд┐рд▓ рд╣реИ, рд╕рд╛рде рд╣реА рд╕рд╛рде рдкреНрд░рддреНрдпреЗрдХ рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐ рдХреЛ рд╢рдХреНрддрд┐ рдкреНрд░рджрд╛рди рдХрд░рдирд╛ред

рдЫрд╡рд┐

рд╕рдВрд╢реЛрдзрд┐рдд (рдЧрддрд┐: 10%):

рдХреБрдЫ рдбрд┐рдЧреНрд░реА рдХреА рдЧрдгрдирд╛ рдХреЛ рдПрдХ рдЪрдХреНрд░ (* * =?) рдореЗрдВ рдХрдо рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдФрд░ рдЕрдиреНрдп factorials рдХреЛ рдкреВрд░реНрд╡-рд╕рдВрдЧрдгрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдФрд░ рдПрдХ рд╕рд░рдгреА рдореЗрдВ рд░рдЦрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдЬрдмрдХрд┐ рд╕рдВрдХреЗрдд (+, -, +, ...) рдХреЛ рдПрдХ рд╢рдХреНрддрд┐ рдореЗрдВ рдирд╣реАрдВ рдЙрдард╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдФрд░ рдЙрдирдХреА рдЧрдгрдирд╛ рднреА рдХрдо рдХреА рдЬрд╛ рд╕рдХрддреА рд╣реИред рдкрд┐рдЫрд▓реЗ рдореВрд▓реНрдпреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реБрдПред

рдкрд░рд┐рдгрд╛рдо рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХреЛрдб рд╣реИ:

рдкрд╛рдк (рдореВрд▓, рдЪрд░рдг)
  // <summary>  ,    Fact </summary> static double[] fact; /// <summary>            . ///   rad,   . ///  ( Math): 4% (fps)  steps = 17 </summary> /// <param name="rad">   .      pi/4. </param> /// <param name="steps">  :  ,   .  pi/4   E-15  8. </param> public static double Sin(double rad, int steps) { double ret; double a; //,     double aa; // *  int i_f; //  int sign; // (  -  +,     = +) ret = 0; sign = -1; aa = rad * rad; a = rad; i_f = 1; //      for (int n = 0; n < steps; n++) { sign *= -1; ret += sign * a / Fact(i_f); a *= aa; i_f += 2; } return ret; } /// <summary>   (n!).  n > fact.Length,  -1. </summary> /// <param name="n"> ,     . </param> public static double Fact(int n) { if (n >= 0 && n < fact.Length) { return fact[n]; } else { Debug.Log("    . n = " + n + ",   = " + fact.Length); return -1; } } /// <summary>  . </summary> static void Init_Fact() { int steps; steps = 46; fact = new double[steps]; fact[0] = 1; for (int n = 1; n < steps; n++) { fact[n] = fact[n - 1] * n; } } 


рд╕реБрдкреАрд░рд┐рдпрд░ рджреГрд╢реНрдп (рдЧрддрд┐: 19%):

рд╣рдо рдЬрд╛рдирддреЗ рд╣реИрдВ рдХрд┐ рдХреЛрдг рдЬрд┐рддрдирд╛ рдЫреЛрдЯрд╛ рд╣реЛрдЧрд╛, рдЙрддрдиреА рд╣реА рдХрдо рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐рдпреЛрдВ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреАред рд╕рдмрд╕реЗ рдЫреЛрдЯрд╛ рдХреЛрдг рдЬрд┐рд╕рдХреА рд╣рдореЗрдВ рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рд╡рд╣ рд╣реИ = 0.25 * PI, рдЕрд░реНрдерд╛рдд 45 рдбрд┐рдЧреНрд░реА рд╕реЗред 45 рдбрд┐рдЧреНрд░реА рдХреЗ рдХреНрд╖реЗрддреНрд░ рдореЗрдВ рдкрд╛рдк рдФрд░ рдХреЙрд╕ рдХреЛ рдзреНрдпрд╛рди рдореЗрдВ рд░рдЦрддреЗ рд╣реБрдП, рд╣рдо рдкрд╛рдк рдХреЗ рд▓рд┐рдП -1 рд╕реЗ 1 рддрдХ рд╕рднреА рдорд╛рди рдкреНрд░рд╛рдкреНрдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ (2 / рдкреАрдЖрдИ рдХреЗ рдХреНрд╖реЗрддреНрд░ рдореЗрдВ)ред рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рд╕рд░реНрдХрд▓ (2 * PI) рдХреЛ 8 рднрд╛рдЧреЛрдВ рдореЗрдВ рд╡рд┐рднрд╛рдЬрд┐рдд рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рдкреНрд░рддреНрдпреЗрдХ рднрд╛рдЧ рдХреЗ рд▓рд┐рдП рд╣рдо рд╕рд╛рдЗрди рдХреА рдЧрдгрдирд╛ рдХрд░рдиреЗ рдХреЗ рдЕрдкрдиреЗ рддрд░реАрдХреЗ рдХрд╛ рд╕рдВрдХреЗрдд рджреЗрддреЗ рд╣реИрдВред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдЧрдгрдирд╛ рдХреЛ рдЧрддрд┐ рджреЗрдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рд╢реЗрд╖ (%) рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рдХрд╛рд░реНрдп рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рд╕реЗ рдЗрдВрдХрд╛рд░ рдХрд░ рджреЗрдВрдЧреЗ (45 рдбрд┐рдЧреНрд░реА рдХреЗ рдХреНрд╖реЗрддреНрд░ рдХреЗ рдЕрдВрджрд░ рдХреЛрдг рдХреА рд╕реНрдерд┐рддрд┐ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП):

рд╕рд┐рди реи (рд░реЗрдб)
  // <summary>  ,    Fact </summary> static double[] fact; /// <summary>   Sin </summary> /// <param name="rad"></param> public static double Sin_2(double rad) { double rad_025; int i; //rad = rad % PI2; //% -   .  , fps   90  150 (  100 000   ) //rad_025 = rad % PI025; i = (int)(rad / PI025); rad_025 = rad - PI025 * i; i = i & 7; //     8  //    switch (i) { case 0: return Sin(rad_025, 8); case 1: return Cos(PI025 - rad_025, 8); case 2: return Cos(rad_025, 8); case 3: return Sin(PI025 - rad_025, 8); case 4: return -Sin(rad_025, 8); case 5: return -Cos(PI025 - rad_025, 8); case 6: return -Cos(rad_025, 8); case 7: return -Sin(PI025 - rad_025, 8); } return 0; } /// <summary>            . ///   rad,   . ///  ( Math): 10% (fps)  steps = 17 </summary> /// <param name="rad">   .      pi/4. </param> /// <param name="steps">  :  ,   .  pi/4   E-15  8. </param> public static double Sin(double rad, int steps) { double ret; double a; //,     double aa; // *  int i_f; //  int sign; // (  -  +,     = +) ret = 0; sign = -1; aa = rad * rad; a = rad; i_f = 1; //      for (int n = 0; n < steps; n++) { sign *= -1; ret += sign * a / Fact(i_f); a *= aa; i_f += 2; } return ret; } /// <summary>            . ///   rad,   . ///  ( Math): 10% (fps), 26% (test)  steps = 17 </summary> /// <param name="rad">   .      pi/4. </param> /// <param name="steps">  :  ,   .  pi/4   E-15  8. </param> public static double Cos(double rad, int steps) { double ret; double a; double aa; // *  int i_f; //  int sign; // (  -  +,     = +) ret = 0; sign = -1; aa = rad * rad; a = 1; i_f = 0; //      for (int n = 0; n < steps; n++) { sign *= -1; ret += sign * a / Fact(i_f); a *= aa; i_f += 2; } return ret; } /// <summary>   (n!).  n > fact.Length,  -1. </summary> /// <param name="n"> ,     . </param> public static double Fact(int n) { if (n >= 0 && n < fact.Length) { return fact[n]; } else { Debug.Log("    . n = " + n + ",   = " + fact.Length); return -1; } } /// <summary>  . </summary> static void Init_Fact() { int steps; steps = 46; fact = new double[steps]; fact[0] = 1; for (int n = 1; n < steps; n++) { fact[n] = fact[n - 1] * n; } } 


рдмрд╣реБрдЖрдпрд╛рдореА рдкрдж


рдореИрдВ рдЗрдВрдЯрд░рдиреЗрдЯ рдкрд░ рдЗрд╕ рдкрджреНрдзрддрд┐ рдХреЗ рдкрд╛рд░ рдЖрдпрд╛ рдерд╛, рд▓реЗрдЦрдХ рдХреЛ рдкреВрд░реНрд╡-рдкрд░рд┐рдХрд▓рд┐рдд рдореВрд▓реНрдпреЛрдВ рдХреЗ рдкреБрд╕реНрддрдХрд╛рд▓рдпреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдП рдмрд┐рдирд╛ рдХрдо рд╕рдЯреАрдХрддрд╛ (рддреНрд░реБрдЯрд┐ <0.000 001) рдХреЗ рдбрдмрд▓ рдХреЗ рд▓рд┐рдП рдПрдХ рддреЗрдЬрд╝ рдкрд╛рдк рдЦреЛрдЬ рдлрд╝рдВрдХреНрд╢рди рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдереАред

рдкреЗрд╢реЗрд╡рд░реЛрдВ:

  • рдЙрдЪреНрдЪ рдЧрддрд┐ (9-84%)
    рдкреНрд░рд╛рд░рдВрдн рдореЗрдВ, рдкрд░рд┐рд╡рд░реНрддрди рдХреЗ рдмрд┐рдирд╛ рдлреЗрдВрдХреЗ рдЧрдП рдмрд╣реБрдкрдж рдХреЛ рдореВрд▓ Math.Sin рдХреА 9% рдХреА рдЧрддрд┐ рджрд┐рдЦрд╛рдИ рдЧрдИ, рдЬреЛ рдХрд┐ 10 рдЧреБрдирд╛ рдзреАрдореА рд╣реИред рдЫреЛрдЯреЗ рдкрд░рд┐рд╡рд░реНрддрдиреЛрдВ рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рдж, рдЧрддрд┐ рддреЗрдЬреА рд╕реЗ 84% рддрдХ рдмрдврд╝ рдЬрд╛рддреА рд╣реИ, рдЬреЛ рдЦрд░рд╛рдм рдирд╣реАрдВ рд╣реИ рдпрджрд┐ рдЖрдк рд╕рдЯреАрдХрддрд╛ рдХреЗ рд▓рд┐рдП рдЕрдкрдиреА рдЖрдБрдЦреЗрдВ рдмрдВрдж рдХрд░рддреЗ рд╣реИрдВред
  • рдХреЛрдИ рдЕрддрд┐рд░рд┐рдХреНрдд рдкреНрд░рд╛рд░рдВрднрд┐рдХ рдЧрдгрдирд╛ рдФрд░ рд╕реНрдореГрддрд┐ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ
    рдпрджрд┐ рдКрдкрд░ рдФрд░ рдиреАрдЪреЗ рд╣рдореЗрдВ рдЧрдгрдирд╛рдУрдВ рдХреЛ рддреЗрдЬ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЪрд░ рдХреЗ рд╕рд░рдгрд┐рдпреЛрдВ рдХреА рд░рдЪрдирд╛ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рддреЛ рдпрд╣рд╛рдВ рд╕рднреА рдкреНрд░рдореБрдЦ рдЧреБрдгрд╛рдВрдХреЛрдВ рдХреА рдЧрдгрдирд╛ рдХреА рдЧрдИ рд╣реИ рдФрд░ рд▓реЗрдЦрдХ рджреНрд╡рд╛рд░рд╛ рд╕реНрдерд┐рд░рд╛рдВрдХ рдХреЗ рд░реВрдк рдореЗрдВ рд╕реНрд╡рдпрдВ рд╕реВрддреНрд░ рдореЗрдВ рд░рдЦрд╛ рдЧрдпрд╛ рд╣реИред
  • Mathf.Sin (рдлреНрд▓реЛрдЯ) рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рд╕рдЯреАрдХрддрд╛
    рддреБрд▓рдирд╛ рдХреЗ рд▓рд┐рдП:

    0.84147 1 - Mathf.Sin (1) (рдПрдХрддрд╛ рдЗрдВрдЬрди);
    0.841470984807897 - Math.Sin (1) (рдорд╛рдирдХ C # рдлрд╝рдВрдХреНрд╢рди);
    0.8414709 56802368 - рдкрд╛рдк (1) (GPU, hlsl рднрд╛рд╖рд╛);
    0.84147 1184637935 - рд╕рд┐рди_0 (1) ред

рд╡рд┐рдкрдХреНрд╖:

  • рд╕рд╛рд░реНрд╡рднреМрдорд┐рдХ рдирд╣реАрдВ рд╣реИ
    рдЖрдк рдореИрдиреНрдпреБрдЕрд▓ рд░реВрдк рд╕реЗ рд╕рдЯреАрдХрддрд╛ рдХреЛ рд╕рдорд╛рдпреЛрдЬрд┐рдд рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗ рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рдЬреНрдЮрд╛рдд рдирд╣реАрдВ рд╣реИ рдХрд┐ рд▓реЗрдЦрдХ рдиреЗ рдЗрд╕ рдмрд╣реБрдкрдж рдХреА рдЧрдгрдирд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рди рдЙрдкрдХрд░рдгреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рд╣реИред
  • рдХреНрдпреЛрдВ?
    рд▓реЗрдЦрдХ рдХреЛ рдПрдХ рдлрд╝рдВрдХреНрд╢рди рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдХреНрдпреЛрдВ рдереА рдЬрд┐рд╕рдореЗрдВ рдХрд┐рд╕реА рднреА рд╕рд░рдгрд┐рдпреЛрдВ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реЛрддреА рд╣реИ рдФрд░ рдЬрд┐рд╕рдореЗрдВ рдЗрддрдиреА рдХрдо (рджреЛрд╣рд░реА рдХреА рддреБрд▓рдирд╛ рдореЗрдВ) рд╕рдЯреАрдХрддрд╛ рд╣реЛрддреА рд╣реИ?

рдореВрд▓ рджреГрд╢реНрдп:

рдкрд╛рдк рез (x)
 /// <summary>  ( Math): 9% (fps)</summary> /// <param name="x">     -2*Pi  2*Pi </param> public static double Sin_1(double x) { return 0.9999997192673006 * x - 0.1666657564532464 * Math.Pow(x, 3) + 0.008332803647181511 * Math.Pow(x, 5) - 0.00019830197237204295 * Math.Pow(x, 7) + 2.7444305061093514e-6 * Math.Pow(x, 9) - 2.442176561869478e-8 * Math.Pow(x, 11) + 1.407555708887347e-10 * Math.Pow(x, 13) - 4.240664814288337e-13 * Math.Pow(x, 15); } 


рдмреЗрд╣рддрд░ рджреГрд╢реНрдп:

рд╕рд┐рди_0 (рд░реЗрдб)
 /// <summary>  ( Math): 83% (fps)</summary> /// <param name="rad">     -2*Pi  2*Pi </param> public static double Sin_0(double rad) { double x; double xx; double ret; xx = rad * rad; x = rad; //1 ret = 0.9999997192673006 * x; x *= xx; //3 ret -= 0.1666657564532464 * x; x *= xx; //5 ret += 0.008332803647181511 * x; x *= xx; //7 ret -= 0.00019830197237204295 * x; x *= xx; //9 ret += 2.7444305061093514e-6 * x; x *= xx; //11 ret -= 2.442176561869478e-8 * x; x *= xx; //13 ret += 1.407555708887347e-10 * x; x *= xx; //15 ret -= 4.240664814288337e-13 * x; return ret; } 


рд░реИрдЦрд┐рдХ рдкреНрд░рдХреНрд╖реЗрдк


рдпрд╣ рд╡рд┐рдзрд┐ рдПрдХ рд╕рд░рдгреА рдореЗрдВ рджреЛ рд░рд┐рдХреЙрд░реНрдб рдХреЗ рдкрд░рд┐рдгрд╛рдореЛрдВ рдХреЗ рдмреАрдЪ рд░реИрдЦрд┐рдХ рдкреНрд░рдХреНрд╖реЗрдк рдкрд░ рдЖрдзрд╛рд░рд┐рдд рд╣реИред
рдкреНрд░рд╡рд┐рд╖реНрдЯрд┐рдпреЛрдВ рдХреЛ mem_sin рдФрд░ mem_cos рдореЗрдВ рд╡рд┐рднрд╛рдЬрд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдЙрдирдХреЗ рдкрд╛рд╕ рдорд╛рдирдХ рдлрд╝рдВрдХреНрд╢рди Math.Sin рдФрд░ Math.Cos рдХреЗ рдкреВрд░реНрд╡-рдкрд░рд┐рдХрд▓рд┐рдд рдкрд░рд┐рдгрд╛рдо рд╣реИрдВред рдЗрдирдкреБрдЯ рдорд╛рдкрджрдВрдбреЛрдВ рдХреЗ рдПрдХ рд╕реЗрдЧрдореЗрдВрдЯ рдкрд░ 0 рд╕реЗ 0.25 * PI рддрдХред

0 рд╕реЗ 45 рдбрд┐рдЧреНрд░реА рдХреЗ рдХреЛрдг рдХреЗ рд╕рд╛рде рдЬреЛрдбрд╝рддреЛрдбрд╝ рдХрд╛ рд╕рд┐рджреНрдзрд╛рдВрдд рдЯреЗрд▓рд░ рд╢реНрд░реГрдВрдЦрд▓рд╛ рдХреЗ рдмреЗрд╣рддрд░ рд╕рдВрд╕реНрдХрд░рдг рд╕реЗ рдЕрд▓рдЧ рдирд╣реАрдВ рд╣реИ, рд▓реЗрдХрд┐рди рдПрдХ рд╣реА рд╕рдордп рдореЗрдВ рдПрдХ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ рдЬреЛ рдкрд╛рддрд╛ рд╣реИ - рдЬрд┐рд╕рдХреЗ рдмреАрдЪ рджреЛ рд░рд┐рдХреЙрд░реНрдб рдПрдХ рдХреЛрдг рд╣реИ - рдФрд░ рдЙрдирдХреЗ рдмреАрдЪ рдПрдХ рдорд╛рди рдкрд╛рддрд╛ рд╣реИред

рдкреЗрд╢реЗрд╡рд░реЛрдВ:

  • рдЙрдЪреНрдЪ рдЧрддрд┐ (65%)
    рдкреНрд░рдХреНрд╖реЗрдк рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдХреА рд╕рд╛рджрдЧреА рдХреЗ рдХрд╛рд░рдг, рдЧрддрд┐ Math.Sin рдХреА рдЧрддрд┐ рдХрд╛ 65% рддрдХ рдкрд╣реБрдВрдЪ рдЬрд╛рддреА рд╣реИред рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдЧрддрд┐> 33% рд╕рдВрддреЛрд╖рдЬрдирдХ рд╣реИред
  • рдЙрдЪреНрдЪрддрдо рдкрд░рд┐рд╢реБрджреНрдзрддрд╛
    рдЕрд╕реНрд╡реАрдХреГрддрд┐ рдХреЗ рдПрдХ рджреБрд░реНрд▓рдн рдорд╛рдорд▓реЗ рдХрд╛ рдПрдХ рдЙрджрд╛рд╣рд░рдг:
    0.255835595715180 - рдореИрде.рдЗрди;
    0.2558355957151 79 - рдкрд╛рдк_3 ред
  • рддреЗрдЬреА рд╕реЗ рдкреИрд░
    рдореБрдЭреЗ рдпрд╣ рдлрд╝рдВрдХреНрд╢рди рдмрд╣реБрдд рдкрд╕рдВрдж рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рдореЗрд░реЗ рджреНрд╡рд╛рд░рд╛ рд▓рд┐рдЦреА рдЧрдИ рдкреАрдбрд╝рд╛ рдореЗрдВ рдкреИрджрд╛ рд╣реБрдЖ рдерд╛ рдФрд░ рдЖрд╡рд╢реНрдпрдХрддрд╛рдУрдВ рд╕реЗ рдЕрдзрд┐рдХ рдерд╛: рдЧрддрд┐> 33%, рд╕рдЯреАрдХрддрд╛ 1e-14 рд╕реЗ рдКрдкрд░ред рдореИрдВ рдЙрд╕реЗ рдПрдХ рдЧреМрд░рд╡рд╢рд╛рд▓реА рдирд╛рдо рджреВрдВрдЧрд╛ - V─Уl givex Pesред

рд╡рд┐рдкрдХреНрд╖:

  • рдЗрд╕рдХреЗ рд▓рд┐рдП рд╕реНрдореГрддрд┐ рдореЗрдВ рдЬрдЧрд╣ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ
    рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рдкрд╣рд▓реЗ рджреЛ рд╕рд░рдгрд┐рдпреЛрдВ рдХреА рдЧрдгрдирд╛ рдХрд░рдиреА рдЪрд╛рд╣рд┐рдП: рдкрд╛рдк рдХреЗ рд▓рд┐рдП рдФрд░ рдХреЙрд╕ рдХреЗ рд▓рд┐рдП; рдкреНрд░рддреНрдпреЗрдХ рд╕рд░рдгреА рдХрд╛ рд╡рдЬрди ~ 16mb (16 * 2 = 32mb)

рдореВрд▓ рджреГрд╢реНрдп:

рд╕рд┐рди_3 (рд░реЗрдб)
 class Math_d { const double PI025 = Math.PI / 4; /// <summary> 2^17 = 131072 (1 ),   10000 ( ),  2^21 = 22097152 (16 )   +-1 ( ) (  ) </summary> const int length_mem = 22097152; const int length_mem_M1 = length_mem - 1; /// <summary>    sin,    . </summary> static double[] mem_sin; /// <summary>    cos,    . </summary> static double[] mem_cos; /// <summary>  ,   sin,    . </summary> public static void Initialise() { Ini_Mem_Sin(); Ini_Mem_Cos(); } /// <summary>       Cos,   . </summary> /// <param name="rad"></param> public static double Sin_3(double rad) { double rad_025; int i; //    //if (rad < 0) { rad = -rad + Math.PI; } i = (int)(rad / PI025); //   rad_025 = rad - PI025 * i; //     ( ) i = i & 7; //      8 //    switch (i) { case 0: return Sin_Lerp(rad_025); case 1: return Cos_Lerp(PI025 - rad_025); case 2: return Cos_Lerp(rad_025); case 3: return Sin_Lerp(PI025 - rad_025); case 4: return -Sin_Lerp(rad_025); case 5: return -Cos_Lerp(PI025 - rad_025); case 6: return -Cos_Lerp(rad_025); case 7: return -Sin_Lerp(PI025 - rad_025); } return 0; } /// <summary>   sin    </summary> static void Ini_Mem_Sin() { double rad; mem_sin = new double[length_mem]; for (int i = 0; i < length_mem; i++) { rad = (i * PI025) / length_mem_M1; mem_sin[i] = Math.Sin(rad); } } /// <summary>   cos    </summary> static void Ini_Mem_Cos() { double rad; mem_cos = new double[length_mem]; for (int i = 0; i < length_mem; i++) { rad = (i * PI025) / length_mem_M1; mem_cos[i] = Math.Cos(rad); } } /// <summary>      sin  0  pi/4. </summary> /// <param name="rad">     0  pi/4. </param> static double Sin_Lerp(double rad) { int i_0; int i_1; double i_0d; double percent; double a; double b; double s; percent = rad / PI025; i_0d = percent * length_mem_M1; i_0 = (int)i_0d; i_1 = i_0 + 1; a = mem_sin[i_0]; b = mem_sin[i_1]; s = i_0d - i_0; return Lerp(a, b, s); } /// <summary>      cos  0  pi/4. </summary> /// <param name="rad">     0  pi/4. </param> static double Cos_Lerp(double rad) { int i_0; int i_1; double i_0d; double percent; double a; double b; double s; percent = rad / PI025; i_0d = percent * length_mem_M1; i_0 = (int)i_0d; i_1 = i_0 + 1; a = mem_cos[i_0]; b = mem_cos[i_1]; s = i_0d - i_0; return Lerp(a, b, s); } /// <summary>      . (return a + s * (b - a)) </summary> /// <param name="a">  . </param> /// <param name="b">  . </param> /// <param name="s">  . 0 = a, 1 = b, 0.5 =   a  b. </param> public static double Lerp(double a, double b, double s) { return a + s * (b - a); } } 



UPD: Sin_Lerp (), Cos_Lerp (), Ini_Mem_Sin () рдФрд░ Ini_Mem_Cos () рдореЗрдВ рд╕реВрдЪрдХрд╛рдВрдХ рдХреЗ рдирд┐рд░реНрдзрд╛рд░рдг рдореЗрдВ рдирд┐рд╢реНрдЪрд┐рдд рддреНрд░реБрдЯрд┐ред

Source: https://habr.com/ru/post/hi426355/


All Articles