首页 > 解决方案 > 了解 For 循环的每个元素的循环数

问题描述

我(模糊地)理解每指令周期(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会下降吗?因为遍历所有元素需要更少的周期?

标签: c++optimizationcpu-architecture

解决方案


(您的代码示例取自教科书《计算机系统:程序员的视角》。)

每个元素的周期是这里的更高级别的指标。与测量 CPI 或 IPC 不同,对示例循环重要的实际单位是向量的元素。因此,在跨越数百或数千个元素运行循环并测量整个执行所需的周期时,我们可以绘制结果测量结果并计算斜率(即每个元素的周期数)。

在移动括号时,这改变了操作的关联,从而将两个数据元素的 OP 改变为独立的。如果有足够的硬件资源来执行额外的独立操作,这可以提高循环的 CPE。

要点应该是确定即使是对代码的简单更改是否会改善执行时间也很困难,因为它依赖于系统的所有部分。通常,程序员应该依靠编译器及其出色的优化来获得良好的性能,而无需求助于细粒度的调整。


推荐阅读