【发布时间】:2011-12-27 07:42:31
【问题描述】:
我有以下代码:
#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:我查看了编译器的手册,但是那里的标志太多了,无法测试哪一个真正有所作为。
【问题讨论】:
-
-O2 执行“不以空间换速度的所有优化”,因此编译器很可能优化了这些循环中的大部分,用编译时数学(即常量)替换它们。就我个人而言,我无法在脑海中做到这一点,但编译器肯定可以弄清楚如何在更少的 OP 中多次添加相同的数组元素。 GCC 特别擅长做很棒的编译时东西。所以它只会归结为一个或两个嵌套循环......这就是它更快的原因。话虽如此,使用
-save-temps编译并查看.s文件。那你肯定知道。 -
你为什么要问?如果您想要更多优化,请告诉编译器。
-O2隐含了一系列优化,-O却没有。如果您希望两者都生成相似的代码,您需要编写不会从-O2添加的任何优化中受益的代码。我不知道那些是什么,但我猜其中有很多通用的。手动添加它们或牺牲一只山羊来阻止它们应用到你的代码中不会帮助你自己。 -
@Alessandro Pezzato:数组的所有元素都使用该类型的默认构造函数进行初始化。
-
所以...编译器能够优化您的类似代码。听起来一切都按预期工作。就像 delnan 说的,如果你想要它快,告诉编译器进行优化。问自己如何做是没有意义的。编译器会为你做各种各样的事情。让它!
-
QtLearner:算了。你不可能达到你想要的。如果你真的想知道为什么,你必须用 -S 编译并查看编译器生成的机器码。
标签: c++ g++ compiler-optimization