【发布时间】:2015-04-03 04:33:30
【问题描述】:
我对 fitch 软件花费多少时间来进行一些简单的计算感到沮丧。我使用 Intel VTune 对其进行了分析,似乎 52% 的 CPU 时间都花在了 nudists() 函数上:
void nudists(node *x, node *y)
{
/* compute distance between an interior node and tips */
long nq=0, nr=0, nx=0, ny=0;
double dil=0, djl=0, wil=0, wjl=0, vi=0, vj=0;
node *qprime, *rprime;
qprime = x->next;
rprime = qprime->next->back;
qprime = qprime->back;
ny = y->index;
dil = qprime->d[ny - 1];
djl = rprime->d[ny - 1];
wil = qprime->w[ny - 1];
wjl = rprime->w[ny - 1];
vi = qprime->v;
vj = rprime->v;
x->w[ny - 1] = wil + wjl;
if (wil + wjl <= 0.0)
x->d[ny - 1] = 0.0;
else
x->d[ny - 1] = ((dil - vi) * wil + (djl - vj) * wjl) / (wil + wjl);
nx = x->index;
nq = qprime->index;
nr = rprime->index;
dil = y->d[nq - 1];
djl = y->d[nr - 1];
wil = y->w[nq - 1];
wjl = y->w[nr - 1];
y->w[nx - 1] = wil + wjl;
if (wil + wjl <= 0.0)
y->d[nx - 1] = 0.0;
else
y->d[nx - 1] = ((dil - vi) * wil + (djl - vj) * wjl) / (wil + wjl);
} /* nudists */
两条长线占用了总 CPU 时间的 24%。有什么办法可以优化这段代码,尤其是两条长线?另一个消耗大量 CPU 时间的函数是:
void secondtraverse(node *q, double y, long *nx, double *sum)
{
/* from each of those places go back to all others */
/* nx comes from firsttraverse */
/* sum comes from evaluate via firsttraverse */
double z=0.0, TEMP=0.0;
z = y + q->v;
if (q->tip) {
TEMP = q->d[(*nx) - 1] - z;
*sum += q->w[(*nx) - 1] * (TEMP * TEMP);
} else {
secondtraverse(q->next->back, z, nx, sum);
secondtraverse(q->next->next->back, z, nx,sum);
}
} /* secondtraverse */
计算总和的代码占 CPU 时间的 18%。有什么办法让它跑得更快?
完整的源代码可以在这里找到:http://evolution.genetics.washington.edu/phylip/getme.html
【问题讨论】:
-
跑题了,但是为什么你的函数叫
nudists? -
除了改进算法的大 O 之外,优化可能是一门黑暗的艺术。正确的方法通常是修改、分析、重复。如果你能读懂反汇编,那就更好了。您可以通过一些技巧来消除 if/else 分支。您可以通过预先计算
1.0 / (wil + wjl)来消除多余的划分。 -
我不知道 - 不是我写了这个软件。这是开源的。
-
@PhilipStuyck:不,随机抓取一段您没有编写且不理解的代码并要求其他人对其进行优化是无效的。向下投票箭头表示“这个问题显示出很少的研究努力”,似乎就是这种情况。 OP 没有尝试解决他自己的问题(尽管识别热点是一个很好的步骤)
-
@BenVoigt 不确定我是否同意他是否通过分析器运行它并能够在无数其他函数中将此函数确定为罪魁祸首我会说这表明了研究工作。但我可能是错的,如果他只是从那个链接上拿的......
标签: c++ c optimization