罪恶和COS很慢,有没有替代方案? [英] sin and cos are slow, is there an alternatve?
问题描述
我的游戏需要移动一定角度.为此,我可以通过sin和cos获得角度矢量.不幸的是,罪恶与弊端是我的瓶颈.我确定我不需要这么高的精度.是否有C sin& C的替代方案? cos和查找表相当精确但非常快吗?
My game needs to move by a certain angle. To do this I get the vector of the angle via sin and cos. Unfortunately sin and cos are my bottleneck. I'm sure I do not need this much precision. Is there an alternative to a C sin & cos and look-up table that is decently precise but very fast?
我发现了:
float Skeleton::fastSin( float x )
{
const float B = 4.0f/pi;
const float C = -4.0f/(pi*pi);
float y = B * x + C * x * abs(x);
const float P = 0.225f;
return P * (y * abs(y) - y) + y;
}
不幸的是,这似乎不起作用.当我使用这种罪恶而不是C罪恶时,我会得到截然不同的行为.
Unfortunately, this does not seem to work. I get significantly different behavior when I use this sin rather than C sin.
谢谢
推荐答案
对于您的fastSin()
,您应该查看其文档以查看其有效范围.您在游戏中使用的单位可能太大或太小,将它们缩放到适合该功能的预期范围可能会使其工作更好.
For your fastSin()
, you should check its documentation to see what range it's valid on. The units you're using for your game could be too big or too small and scaling them to fit within that function's expected range could make it work better.
Someone else mentioned getting it into the desired range by subtracting PI, but apparently there's a function called fmod
for doing modulus division on floats/doubles, so this should do it:
#include <iostream>
#include <cmath>
float fastSin( float x ){
x = fmod(x + M_PI, M_PI * 2) - M_PI; // restrict x so that -M_PI < x < M_PI
const float B = 4.0f/M_PI;
const float C = -4.0f/(M_PI*M_PI);
float y = B * x + C * x * std::abs(x);
const float P = 0.225f;
return P * (y * std::abs(y) - y) + y;
}
int main() {
std::cout << fastSin(100.0) << '\n' << std::sin(100.0) << std::endl;
}
我不知道fmod
有多昂贵,所以接下来我将尝试快速进行基准测试.
I have no idea how expensive fmod
is though, so I'm going to try a quick benchmark next.
基准测试结果
我用-O2
进行了编译,并使用Unix time
程序运行了结果:
I compiled this with -O2
and ran the result with the Unix time
program:
int main() {
float a = 0;
for(int i = 0; i < REPETITIONS; i++) {
a += sin(i); // or fastSin(i);
}
std::cout << a << std::endl;
}
结果是sin
慢了大约1.8倍(如果fastSin
需要5秒钟,sin
需要9秒钟).准确性似乎还不错.
The result is that sin
is about 1.8x slower (if fastSin
takes 5 seconds, sin
takes 9). The accuracy also seemed to be pretty good.
如果您选择采用这种方法,请确保在(gcc中的-O2
)上进行优化编译.
If you chose to go this route, make sure to compile with optimization on (-O2
in gcc).
这篇关于罪恶和COS很慢,有没有替代方案?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!