创建一个快速Sin()函数来改善fps?快速sin()函数?

max*_*yne 5 c c++ math performance trigonometry

我实时渲染500x500点.我必须使用atan()和sin()函数计算点的位置.通过使用atan()和sin(),我获得24 fps(每秒帧数).

float thetaC = atan(value);
float h = (value) / (sin(thetaC)));
Run Code Online (Sandbox Code Playgroud)

如果我不使用sin(),我得到52 fps.

如果我不使用atan()我是30 fps.

所以,最大的问题是sin().我怎样才能使用Fast Sin版本.我可以为此创建一个查找表吗?我没有任何特定的值来创建LUT.在这种情况下我该怎么办?

PS:我也尝试过快速的ASM功能,但没有任何区别.

谢谢.

pad*_*ddy 10

稍等一下....

你有一个三角形,你正在计算低音.首先,您需要atan(value)获取角度,然后value再次使用sin计算h.所以我们有三角形的一边是1的场景:

   /|
h / | value
 /  |
/C__|
  1
Run Code Online (Sandbox Code Playgroud)

你真正需要做的就是计算h = sqrt(value*value + 1);......但是,sqrt这不是最快的功能.

也许我错过了这一点,或者你已经遗漏了一些东西.我一直使用查找表sincos,并发现他们要快.如果你不提前知道值,那么你需要近似,但这意味着乘法,截断为整数(并可能是符号转换)以获得数组索引.如果你可以将你的单位转换为整数(有效地使你的浮点数成为定点),它会使查找更快.

  • invsqrt SSE指令非常快,因为它牺牲了全精度. (3认同)
  • 根据您的应用程序,有时将所有内容保留为平方值是可以的...通常您可以完全避免三角函数和平方根. (2认同)

Eri*_*ric 6

这取决于您需要的准确性.sin的最大导数是1,所以如果x1和x2在彼此的epsilon之内,则sin(x1)和sin(x2)也在epsilon之内.如果您只需要精确到0.001,那么您可以创建一个1000*PI = 3142点的查找表,并只查找最接近您需要的值.这可能比本机代码更快,因为本机代码(可能)使用多项式系数的查找表,然后进行插值,因为这个表可以小到足以容易地保留在缓存中.

如果你需要在整个范围内完全准确,那么你可以做的更好.

如果你愿意,你也可以在(1/sin(x))上创建一个查找表,因为这是你感兴趣的实际功能.无论哪种方式,你都要小心sin(x)= 0,因为sin(x)中的一个小错误会导致1/sin(x)出现大的错误.定义容错对于确定可以采用的快捷方式非常重要.

您将使用以下内容创建查找表:

float *table = malloc(1000 * sizeof(float));
for(int i = 0; i < 1000; i++){
  table[i] = sin(i/1000.0);
}
Run Code Online (Sandbox Code Playgroud)

并会访问它类似的东西

void fastSin(float x){
  int index = x * 1000.0;
  return table[index];
}
Run Code Online (Sandbox Code Playgroud)

这段代码不完整(并且因为数组边界而因0 <x <1之外的任何事情而崩溃),但是应该让你开始.