在计算机系统:程序员的视角一书中,练习5.5显示了一段用于计算多项式值的代码
double poly(double a[], double x, int degree)
{
long int i;
double result = a[0];
double xpwr = x;
for (i = 1; i <= degree; i++) {
result += a[i] * xpwr;
xpwr = x * xpwr;
}
return result;
}
练习假设双精度浮点加法和乘法所需的时钟周期分别为3和5。要求读者解释为什么测得的CPE(每元素周期数)值为5。
根据练习答案,在每次迭代中,我们需要更新变量xpwr
和result
,我们需要的操作是浮点加法(对于result
)和浮点乘法(对于xpwr
),因此后者支配延迟,导致最终CPE为5.
但我认为数据流应该是这样的:
xpwr result
| |
+-----+ +--[load] |
| | | |
[mul] [mul] |
| | |
| +---+ +-----+
| | |
| [add]
| |
| +------+
| |
xpwr result
因此,最长路径是从xpwr
的先前值到result
的新值,通过执行单位[mul]
和[add]
。因此,最长的时间应该是8个周期。
我想问一下
有关CPU,架构,执行单元,管道,浮点单元的任何解释都将受到赞赏。
答案 0 :(得分:5)
我知道我参加聚会有点晚了,但这本书绝对正确。正如您可以通过计时代码来验证自己,CPE确实是5,所以第二个答案是错误的。
但第一个也错了。它说MUL必须同时执行,这在Nehalem架构中根本不可能(我怀疑,大多数现代处理器)。请记住,只有一个FP MUL单元和一个不同的FP ADD单元(如本书,2011年及以后的版本所示)
相反的是:
(假设LOAD始终存在,如果在缓存中则只有1个周期)
首先我们在MUL中提供xpwr *= x
。紧接着我们喂xpwr*a[i]
(记住管道!)
...在5个周期后,我们将获得xpwr
的新值,经过6个周期后,我们将得到xpwr*a[i]
的结果。此时,xpwr *= x
的新计算将在MUL的第1阶段。因此,如果我们不想被他们限制,我们只剩下4个周期来完成剩下的操作。
当然,这很容易,因为我们只需要3个周期就可以让FP ADD获得新的result
。
因此,很明显,限制因素是xpwr
的计算。这意味着在寻找关键路径(无论是什么)时,我们必须特别注意从旧值到新值的路径。在这种情况下,result
的路径只包含一个FP ADD! (这也是最初让我失望的原因)
答案 1 :(得分:1)
关键路径确实是8个周期,但问题是要求CPE,这就像输出一个循环周期的时间平均时间。
除了第一个和最后一个周期之外,处理器可以同时执行循环的前一次迭代和当前乘法的相加,因为操作数不相互依赖。循环的第一次迭代需要完整的8个循环,但是之后的所有迭代,循环只需要5个循环来运行,使实际的CPE循环5次。
P.S。我同意这本书提出关键路径的方式令人困惑。他们对关键路径的定义不仅仅是采用最长路径的路径,而且路径还必须具有依赖于先前操作的操作数的操作,因此必须按顺序进行。这个定义使得找到关键路径并不直观。
答案 2 :(得分:1)
A1:根据本书,关键路径是数据流图中最长的路径,它必须在一条直线上并对单个寄存器产生影响,而不是加起来“mul&#39;和&#39; add&#39;,其结果只是下一个操作的中间操作数。
关于这个问题,如果继续阅读其余内容,您将完成所有工作。特别是,比较combine7的数据流图和组合5可能会有所帮助。
A2:如果理解A1,问题2是明确的,书中的答案是合理的。
答案 3 :(得分:0)
关键路径是图表中最长的路径,在这种情况下是8个时钟。这就是Dragon Book关于关键路径的说法(10.3.3优先拓扑命令):
没有资源限制,最短的时间表由 关键路径,通过数据依赖图的最长路径。一个 作为优先级函数使用的度量是节点的高度,即 是图中最长路径的长度 节点
我认为你在书中发现了一个错误。您应该考虑与作者联系,以便他们在将来的印刷中纠正它。