编辑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
我要尝试的第一件事是在你的一个条件中反转元素,替换:
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)
| 归档时间: |
|
| 查看次数: |
105 次 |
| 最近记录: |