卡常的时候突然想到一个问题,循环展开为什么要比正常的for和while快?循环展开之后循环体变复杂了,但乘起来时间复杂度不还是O(n)的吗?
因为计算机的运算单元有冗余,可以并行计算(超标量)
还有一个原因就是减少了循环判断、跳转的开销。
【以下回答由 GPT 生成】
循环展开是一种优化技术,可以提高代码的执行效率。它通过在编译时展开循环的迭代次数,从而减少循环体中的判断、跳转等开销。虽然循环展开会导致代码体积增大,但它能够降低循环控制对程序性能的影响。
具体来说,循环展开可以提高代码的局部性,减少了对循环条件判断和循环跳转的需要。同时,循环展开也可以将多个循环迭代重叠执行,并行处理多个循环迭代,从而利用现代处理器的并行计算能力。
下面是一个简单的示例,展示了循环展开的原理:
#include <iostream>
#include <chrono>
const int N = 100000000;
int main() {
int sum = 0;
// 普通循环
auto start1 = std::chrono::high_resolution_clock::now();
for (int i = 0; i < N; i++) {
sum += i;
}
auto end1 = std::chrono::high_resolution_clock::now();
std::chrono::duration<double> diff1 = end1 - start1;
std::cout << "普通循环耗时:" << diff1.count() << " s" << std::endl;
// 循环展开
int sum_unrolled = 0;
auto start2 = std::chrono::high_resolution_clock::now();
for (int i = 0; i < N; i+=4) {
sum_unrolled += i;
sum_unrolled += i+1;
sum_unrolled += i+2;
sum_unrolled += i+3;
}
auto end2 = std::chrono::high_resolution_clock::now();
std::chrono::duration<double> diff2 = end2 - start2;
std::cout << "循环展开耗时:" << diff2.count() << " s" << std::endl;
// 输出结果
std::cout << "普通循环结果:" << sum << std::endl;
std::cout << "循环展开结果:" << sum_unrolled << std::endl;
return 0;
}
上述代码中,我们分别使用普通循环和循环展开的方式计算了1到N的累加和。通过比较两种方式的耗时,我们可以看到循环展开的效率更高。这是因为循环展开在每次迭代中执行了4次累加操作,减少了循环条件判断和循环跳转的开销,从而减少了运行时间。
需要注意的是,循环展开并不是一种绝对能够加速的优化手段,在某些情况下,循环展开可能会增加代码的体积,导致缓存不命中等问题,从而进一步降低程序的性能。因此,在实际使用中,需要根据具体的情况来判断是否使用循环展开技术。
【相关推荐】