我有以下代码:
#include <iostream>
int main()
{
int n = 100;
long a = 0;
int *x = new int[n];
for(int i = 0; i < n; ++i)
for(int j = 0; j < n; ++j)
for(int k = 0; k < n; ++k)
for(int l = 0; l < n; ++l)
{
a += x[(j + k + l) % 100];
}
std::cout << a << std::endl;
delete[] x;
return 0;
}
如果我在没有优化的情况下编译 g++ test.cc 然后运行时 ./a.out 它将显示 0.7s。然而,当我用-O 编译它时,时间减少了 2 倍。
使用的编译器
g++ (Ubuntu/Linaro 4.5.2-8ubuntu4) 4.5.2
我的问题
如何重写代码以便在不使用 -O 的情况下进行编译时可以获得相同的时间(或接近)?换句话说,如何手动优化嵌套循环?
我为什么要问
我有一个类似的代码,如果我使用 -O 优化,它的运行速度大约快 4 倍。
PS:我查看了编译器的手册,但那里有太多的标志来测试哪一个真正有所作为。
最佳答案
编译器使用 -O 优化的大部分内容都是低于 C++ 级别的内容。例如,所有变量都存在于内存中,包括您的循环变量。因此,如果不进行优化,编译器很可能会在内部循环的每次迭代中首先读取循环变量并将其与 0 进行比较,在循环内部再次加载它以便将其用于索引,然后在循环结束时将再次读取该值,将其递增,然后写回。通过优化,它会注意到循环变量在循环体中没有改变,因此不需要每次都从内存中重新读取。此外,它还会注意到变量的地址永远不会被获取,因此没有其他代码会访问它,因此也可以省略将其写入内存的操作。也就是说,循环变量将只存在于内存中。仅此优化一项就可以在函数执行期间节省三亿次内存读取和一亿次内存写入。但由于处理器寄存器和内存读/写等内容未在语言级别公开,因此无法在语言级别对其进行优化。
此外,手动优化编译器无论如何都会优化的东西是没有意义的。最好将时间花在优化编译器无法优化的事情上。
关于c++ - g++ -O 优化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8099479/