微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

了解 For 循环的每个元素的周期数

如何解决了解 For 循环的每个元素的周期数

我(模糊地)理解每指令周期数 (CPI) 和每周期指令数 (IPC) 的含义。 CPI 是执行程序所需的时钟周期数除以运行程序执行的指令数。另一方面,IPC 是运行程序时执行的指令数除以执行程序所需的时钟周期数。

但是,当与循环关联时,我无法理解 Cycles Per Elements 的含义。

例如,在下面的代码中,

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会降低吗?因为遍历所有元素需要更少的周期?

解决方法

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

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

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

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

,

Cycles Per Element 是一个术语,当您在数组、向量或其他元素容器上进行迭代时,用于表示每次循环迭代的 CPU 周期数。对于 combine4(),您将测量运行整个 for 循环所需的 CPU 周期总数,并将其除以 length 以获得 CPE。

现在的编译器非常擅长优化代码,例如它们可能会自动展开或向量化循环。他们还可以改变操作执行的顺序,利用指令时序和其他微架构细节的知识来产生最佳的指令序列,只要能证明这种重新排序不会改变最终结果。因此,手动更改可能不会按照您的预期进行。除了对您的更改进行基准测试之外,您还应该查看编译器的汇编输出以查看它生成的机器代码类型。当然不要忘记启用编译器优化。一个很好的基于网络的工具是 https://godbolt.org/

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。