简单计算的性能问题

Kie*_*son 3 c++ optimization

编辑2:程序计算时间减少16%!见底部进行计算


我编写了一个N体模拟器,实现了Barnes-Hut算法.现在我有一个看起来无辜的功能CheckNode.它的简单并且不需要很长时间来计算,但问题是,它被称为数百万次,因此它占用了每帧之间的大部分计算时间.

我分析了代码,这个函数负责84.58%总的计算时间,这只有10K的粒子,当我用这个高达10倍时,这个函数使用越来越大的百分比.


现在这里是函数,右边的时间占红色的百分比.

在此输入图像描述


现在这里有一些令人担忧的事情,就像一个简单的if语句9.17%和另一个if语句占用超过20%的计算时间!有没有,即使是最轻微的优化可以在这里完成,它将成倍增加数百万个函数调用,以使我的程序运行得更快?

编辑:

这是CalculateForceNode功能:

void CalculateForceNode(Body* bi, Node* bj)  //bi is being attracted to bj. 15 flops of calculation
{
    //vector from the body to the center of mass
    double vectorx = bj->CenterOfMassx - bi->posX;
    double vectory = bj->CenterOfMassy - bi->posY;

    //c^2 = a^2 + b^2 + softener^2
    double distSqr = vectorx * vectorx + vectory * vectory + Softener * Softener;

    // ivnDistCube = 1/distSqr^(3/2)
    double distSixth = distSqr * distSqr * distSqr;
    double invDistCube = 1.0f / (sqrt(distSixth));

    double Accel = (bj->TotalMass * invDistCube * _GRAV_CONST);

    bi->AccelX += vectorx * Accel;
    bi->AccelY += vectory * Accel;
}
Run Code Online (Sandbox Code Playgroud)

编辑2:

优化结果

CheckNode功能现在占用了82.03%总计算时间(在1分37秒的样本中测量),而不是以前占用的时间84.58%.

现在逻辑告诉剩下15%的计算时间,与第二个程序的剩余18%计算时间相同.因此,第一个程序和第二个程序使用了相同的句点(它们是相同的代码).让时间来完成这个其他代码是第一个程序采取= 和第二个采取= .然后,你可以找到馏分是其计算是和为此有一个()程序计算时间的16%下降!15%18%x1/0.156.666x1/0.185.555x5.555x6.666x~0.831 - 0.83 = 0.16

sir*_*rge 6

我要尝试的第一件事是在你的一个条件中反转元素,替换:

if(withSqr / distanceSqr < nodeThresholdSqr || pNode->HasChildren == false)
Run Code Online (Sandbox Code Playgroud)

有:

if(pNode->HasChildren == false || (withSqr / distanceSqr < nodeThresholdSqr))
Run Code Online (Sandbox Code Playgroud)

如果条件的第一部分为真pNode->HasChildren == false,则第二部分(withSqr / distanceSqr < nodeThresholdSqr)将永远不会执行(读取:已评估).检查简单条件比对浮点数操作要快得多(在您的情况下除法).你甚至可以将它提升到一个新的水平:*你需要计算distanceSqrAT ALL pNode->HasChildren == false吗?

编辑:更好:

if(pNode->HasChildren == false)
{
    CalculateForceNode(pBody,pNode);
}
else
{
    double distanceSqr = ((diffX * diffX) + (diffY * diffY));
    double withSqr     = pNode->width * pNode->width;
    if(withSqr / distanceSqr < nodeThresholdSqr)
    {
        CalculateForceNode(pBody,pNode);
    }
    else
    {//if not, repeat function with child
        if(pNode->Child[0]->Bodies.size() > 0)
            CheckNode(pNode->Child[0],pBody);
        //..... - all the rest of your code
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 没有.乔治的安排会为你做到这一点.这就是为什么它更快.也可以考虑根据我的评论用乘法替换除法.要清楚,如果HasChildren为false,则IF语句返回true而不计算第二部分. (2认同)