编译成更快的代码:“n * 3”或“n +(n * 2)”?

时间:2008-09-10 10:44:33

标签: c++ c optimization compiler-construction performance

编译成更快的代码:“ans = n * 3”或“ans = n +(n * 2)”?

假设n是int或long,并且它在现代Win32 Intel盒子上运行。

如果涉及一些解除引用,那么这会有所不同,也就是说,哪一种会更快?


long    a;
long    *pn;
long     ans;

...
*pn = some_number;
ans = *pn * 3;

或者

ans = *pn+(*pn*2);

或者,是否需要不用担心,因为优化编译器在任何情况下都可能会考虑到这一点?

11 个答案:

答案 0 :(得分:55)

IMO这样的微优化是没有必要的,除非你使用一些奇特的编译器。我会把可读性放在第一位。

答案 1 :(得分:15)

没关系。现代处理器可以在一个时钟周期或更短的时间内执行整数MUL指令,这与需要执行一系列移位并在内部添加以执行MUL的旧处理器不同,从而使用多个周期。我敢打赌那个

MUL EAX,3

执行得比

MOV EBX,EAX
SHL EAX,1
ADD EAX,EBX

这种优化可能有用的最后一个处理器可能是486.(是的,这偏向于英特尔处理器,但也可能代表其他架构)。

无论如何,任何合理的编译器都应该能够生成最小/最快的代码。因此,首先要考虑可读性。

答案 2 :(得分:10)

由于自己很容易测量,为什么不这样做呢? (使用来自cygwin的gcctime

/* test1.c */
int main()
{
    int result = 0;
    int times = 1000000000;
    while (--times)
        result = result * 3;
    return result;
}

machine:~$ gcc -O2 test1.c -o test1
machine:~$ time ./test1.exe

real    0m0.673s
user    0m0.608s
sys     0m0.000s

进行几次测试并重复另一次测试。

如果您想查看汇编代码,gcc -S -O2 test1.c

答案 3 :(得分:4)

这取决于编译器,其配置和周围的代码。

如果不进行测量,你不应该试着猜测事情是否“更快”。

总的来说你现在不应该担心这种纳米级优化的东西 - 它几乎总是完全无关紧要,如果你真的在一个重要的领域工作,你就已经在使用探查器并查看编译器的汇编语言输出。

答案 4 :(得分:4)

找出编译器对您的代码执行的操作并不难(我在这里使用DevStudio 2005)。使用以下代码编写一个简单的程序:

int i = 45, j, k;
j = i * 3;
k = i + (i * 2);

在中间行放置一个断点并使用调试器运行代码。触发断点时,右键单击源文件并选择“Go To Disassembly”。您现在将拥有一个包含CPU正在执行的代码的窗口。在这种情况下,您会注意到最后两行产生完全相同的指令,即“lea eax,[ebx + ebx * 2]”(在这种特殊情况下不进行位移和添加)。在现代的IA32 CPU上,由于CPU的流水线特性导致直接使用修改后的值会导致惩罚,因此执行直接MUL而非位移可能更有效。

这展示了aku正在谈论的内容,即编译器足够聪明,可以为您的代码选择最佳指令。

答案 5 :(得分:1)

它取决于您实际使用的编译器,但很可能它们转换为相同的代码。

您可以通过创建一个小型测试程序并检查其反汇编来自行检查。

答案 6 :(得分:1)

大多数编译器足够聪明,可以将整数乘法分解为一系列位移和加法。我不知道Windows编译器,但至少使用gcc你可以让它吐出汇编程序,如果你看一下,你可以看到两种编写方式相同的汇编程序。

答案 7 :(得分:1)

它并不关心。我认为有更重要的事情需要优化。你花了多少时间思考和编写这个问题而不是自己编码和测试?

: - )

答案 8 :(得分:1)

只要你使用一个不错的优化编译器,只需编写代码,编译器就可以轻松理解。这使编译器更容易执行巧妙的优化。

您问这个问题表明优化编译器比您更了解优化。所以相信编译器。使用n * 3

同时查看this answer

答案 9 :(得分:0)

编译器擅长优化您的代码。任何现代编译器都会为这两种情况生成相同的代码,另外用左移替换* 2

答案 10 :(得分:0)

相信你的编译器可以像这样优化一小段代码。可读性在代码级别更为重要。真正的优化应该达到更高的水平。