我有一段代码,每次追踪4条正弦曲线。
我的原始代码在每帧大约调用了12000个sin()函数,并以30fps的速度运行。
我尝试通过生成查找表进行优化。最终我得到了16个不同的查找表。我在程序顶部声明并加载它们,存放在一个单独的头文件中。每个表的声明方式如下:
static const float d4_lookup[800] {...};
现在,使用这种新的方法我实际上失去了fps吗?现在我的帧率只有20而不是30.每个帧现在只需要进行8次sin / cos调用和19200次查找调用,而不是12000次sin()调用。我使用gcc编译,并带有-O3标志。目前,查找表被包含在顶部,并且是程序的全局范围的一部分。
我认为我没有以正确的内存方式加载它们或类似的原因。如何加快查找时间?
**编辑1**
按要求,这是使用查找调用的函数,它每帧调用一次:
void
update_sines(void)
{
static float c1_sin, c1_cos;
static float c2_sin, c2_cos;
static float c3_sin, c3_cos;
static float c4_sin, c4_cos;
clock_gettime(CLOCK_MONOTONIC, &spec);
s = spec.tv_sec;
ms = spec.tv_nsec * 0.0000001;
etime = concatenate((long)s, ms);
c1_sin = sinf(etime * 0.00525);
c1_cos = cosf(etime * 0.00525);
c2_sin = sinf(etime * 0.007326);
c2_cos = cosf(etime * 0.007326);
c3_sin = sinf(etime * 0.0046);
c3_cos = cosf(etime * 0.0046);
c4_sin = sinf(etime * 0.007992);
c4_cos = cosf(etime * 0.007992);
int k;
for (k = 0; k < 800; ++k)
{
sine1[k] = a1_lookup[k] * ((bx1_sin_lookup[k] * c1_cos) + (c1_sin * bx1_cos_lookup[k])) + d1_lookup[k];
sine2[k] = a2_lookup[k] * ((bx2_sin_lookup[k] * c2_cos) + (c2_sin * bx2_cos_lookup[k])) + d2_lookup[k] + 50;
sine3[k] = a3_lookup[k] * ((bx3_sin_lookup[k] * c3_cos) + (c3_sin * bx3_cos_lookup[k])) + d3_lookup[k];
sine4[k] = a4_lookup[k] * ((bx4_sin_lookup[k] * c4_cos) + (c4_sin * bx4_cos_lookup[k])) + d4_lookup[k] + 50;
}
}
**更新**
对于任何看到这个帖子的人,我已经放弃了解决这个问题。我尝试使用OpenCL内核、结构体、SIMD指令以及所有在这里展示的解决方案。最终,计算每帧12800个sinf()函数原始代码比查找表更快,因为查找表无法适应缓存。但它仍然只能达到30fps。它有太多要做的事情,无法满足我想要的60fps期望。我决定采取不同的方向。感谢每个为此帖子做出贡献的人。大多数这些解决方案可能会有一些像我想要的200%速度提升,但是没有什么可以让查找表像我想要的那样工作。
sine
本身和仅为sine
创建单个查找函数?减少内存吞吐量(不加载所有16个查找表...)。还要记住,sin a = cos (a-PI/2)
。它是周期性的,因此一个单独的查找表和参数修改就足够了。 - Dariusz