罪恶和COS很慢,有没有替代方案? [英] sin and cos are slow, is there an alternatve?

查看:72
本文介绍了罪恶和COS很慢,有没有替代方案?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的游戏需要移动一定角度.为此,我可以通过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.

有人提到通过减去PI使其达到所需范围,但显然有一个名为

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆