Why is my sine algorithm much slower than the default?
const double pi = 3.1415926535897;
static double mysin(double x) {
return ((((((-0.000140298 * x - 0.00021075890) * x + 0.008703147) * x -
0.0003853080) * x - 0.16641544) * x - 0.00010117316) * x +
1.000023121) * x;
}
static void Main(string[] args) {
Stopwatch sw = new Stopwatch();
double a = 0;
double[] arg = new double[1000000];
for (int i = 0; i < 1000000; i++) {
arg[i] = (pi / 2000000);
}
sw.Restart();
for (int i = 0; i < 1000000; i++) {
a = a + Math.Sin(arg[i]);
}
sw.Stop();
double t1 = (double)(sw.Elapsed.TotalMilliseconds);
a = 0;
sw.Restart();
for (int i = 0; i < 1000000; i++) {
a = a + mysin(arg[i]);
}
sw.Stop();
double t2 = (double)(sw.Elapsed.TotalMilliseconds);
Console.WriteLine("{0}n{1}n", t1,t2);
Console.Read();
}
This power series is valid for [0,pi/2] and it is 10 times slower than the built in sine function in release mode. 1ms vs 10ms.
But when I copy paste mysin
code into the function I get practically the same time in release and my code is about 4 times faster when in debug mode.
a = 0;
sw.Restart();
for (int i = 0; i < 1000000; i++) {
double x = arg[i];
a = a + ((((((-0.000140298 * x - 0.00021075890) * x + 0.008703147) * x -
0.0003853080) * x - 0.16641544) * x - 0.00010117316) * x +
1.000023121) * x;
//a = a + mysin(arg[i]);
}
What is the deal here? How do I make this sort of calculations faster? I am guessing the code automatically recognizes that sin algorithm should not be called but copy paste into the loop. How do I make the compiler do the same for me.
One more question, would c++ do the same optimization for its default sin/cos function? If not how would I make sure that it does. Edit: I tested it and my sine function (with 4 extra if conditions added to expand the domain to all real) runs about 25% faster (albeit inaccurate) than the default sin function. And in fact, the copy pasted version runs slower than when I write it as a separate function.
I assume that you tested this on x86, because I cannot repro the numbers on x64. On x64, your code actually appears to be faster.
I disassembled the code for x86/release. The reason for the difference is that your method is just that, a method whereas Math.Sin
is compiled to use the x86 fsin
instruction directly thus eliminating a function call per invocation.
FWIW, the x64 code is quite different. Math.Sin
is translated into clr!COMDouble::Sin
.
See FSIN.
链接地址: http://www.djcxy.com/p/28020.html上一篇: WebGL:将spritebatch渲染为渲染纹理时的奇怪行为
下一篇: 为什么我的正弦算法比默认的算法慢得多?