我(模糊地)理解了每指令周期数(CPI)和每周期指令数(IPC)是什么意思。CPI是执行程序所需的时钟周期数除以运行程序所执行的指令数。另一方面,IPC是运行程序时执行的指令数除以执行程序所需的时钟周期数。
然而,当与循环相关联时,我很难理解每个元素的循环意味着什么。
例如,在以下代码中,
void combine4(vec_ptr v, data_t *dest) {
long i;
long length = vec_length(v);
data_t *d = get_vec_start(v);
data_t t = IDENT;
for (i = 0; i < length; i++)
t = t OP d[i];
*dest = t;
}我们可以通过改变for循环样式来进行多个优化。
一种方法称为循环展开
/* Combine 2 elements at a time */
for (i = 0; i < limit; i += 2) {
x = (x OP d[i]) OP d[i + 1];
}
/* Finish any remaining elements */
for (; i < length; i++) {
x = x OP d[i];
}为了进一步改进它,我们可以用括号将数组访问括起来。
x = x OP (d[i] OP d[i + 1]);我相信我们开始计算下一个循环的信息是因为我们没有相关数据。术语CPE如何应用于此优化?CPE会降低吗?因为它需要更少的周期来运行所有的元素?
发布于 2021-06-08 02:58:56
(您的代码示例取自教科书“计算机系统:程序员的视角”。)
在这里,每个元素的周期数是一个更高级别的度量。与测量CPI或IPC不同,对示例循环重要的实际单位是向量的元素。因此,在跨越数百或数千个元素运行循环并测量整个执行所需的周期时,我们可以绘制结果测量值并计算斜率(即每个元素的周期)。
在移动括号时,这改变了操作的关联,从而将两个数据元素的OP更改为独立的。如果有足够的硬件资源来执行额外的独立操作,这可以提高循环的CPE。
结论应该是,确定即使是对代码的简单更改是否会缩短执行时间也是困难的,因为它依赖于系统的所有部分。通常,程序员应该依靠编译器及其出色的优化来实现良好的性能,而不需要求助于细粒度的调优。
发布于 2021-06-08 02:47:29
每元素的周期数是指在迭代数组、向量或其他元素容器时循环的每次迭代的CPU周期数。对于combine4(),您将测量运行整个for-loop所需的总CPU周期数,然后将其除以length得到CPE。
现在的编译器非常擅长优化代码,例如,他们可能会自动展开或向量化循环。它们还可以改变操作的执行顺序,使用指令时序和其他微体系结构细节的知识来产生最优的指令序列,只要它能证明这种重新排序不会改变最终结果。因此,手动更改可能不会实现预期的效果。除了对您的更改进行基准测试之外,您还应该查看编译器的汇编输出,以了解它生成了什么类型的机器码。当然,不要忘记启用编译器优化。https://godbolt.org/是一个很好的基于web的工具。
https://stackoverflow.com/questions/67876904
复制相似问题