3

我正在研究一个生成“S曲线”的伽玛函数。我需要在实时环境中运行它,所以我需要尽可能加快它的速度。

代码如下:

float Gamma = 2.0f; //Input Variable

float GammaMult = pow(0.5f, 1.0f-Gamma);
if(Input<1.0f && Input>0.0f)
{
    if(Input<0.5f)
    {
        Output = pow(Input,Gamma)*GammaMult;
    }
    else
    {
        Output  = 1.0f-pow(1.0f-Input,Gamma)*GammaMult;
    }
}
else
{
   Output  = Input;
}

有什么办法可以优化这段代码吗?

4

2 回答 2

3

如果指令集支持饱和算术或使用最大/最小内在函数,例如x86 MAXSS ,您可以通过消除分支来避免流水线停顿Input<1.0f && Input>0.0f

您还应该通过舍入饱和来消除其他分支Input。完整算法:

float GammaMult = pow(0.5f, 1.0f-Gamma);
Input = saturate(Input); // saturate via assembly or intrinsics
// Input is now in [0, 1]
Rounded = round(Input); // round via assembly or intrinsics
Coeff = 1 - 2 * Rounded
Output = Rounded + Coeff * pow(Rounded + Coeff * Input,Gamma)*GammaMult;

舍入也应该通过 asm/intrinsics完成。

如果您在例如数组的连续值上使用此函数,如果目标体系结构支持 SIMD,您应该考虑对其进行矢量化。

于 2016-01-18T12:49:49.187 回答
0

你的代码看起来不错。瓶颈(如果存在)是pow功能。唯一的解决方案是更深入地了解底层细节并尝试实现自己的pow功能。例如,如果 2 个浮点数对您来说就足够了,您可能会发现一些更快的基于近似的算法。

看到这个:在浮点中实现 pow() 函数的最有效方法

于 2016-01-18T12:40:39.583 回答