简体   繁体   English

为什么一项任务比另一项任务更快?

[英]Why is one assignment faster than the other?

I heard a lot people saying 我听到很多人说

int a = 0;
a += 10;

is faster than 比...快

int a = 0;
a = a + 10;

Why is that? 这是为什么? I debugged it with gdb and it was absolutely the same instructions. 我用gdb调试了它,它是完全相同的指令。

gdb : gdb:

First 第一

(gdb) list
1   int main()
2   {
3       int counter = 0;
4       counter = counter + 10;
5       return 0;
6   }
(gdb) disassemble main
Dump of assembler code for function main:
   0x00000000004004cc <+0>: push   %rbp
   0x00000000004004cd <+1>: mov    %rsp,%rbp
   0x00000000004004d0 <+4>: movl   $0x0,-0x4(%rbp)
   0x00000000004004d7 <+11>:    addl   $0xa,-0x4(%rbp)
=> 0x00000000004004db <+15>:    mov    $0x0,%eax
   0x00000000004004e0 <+20>:    pop    %rbp
   0x00000000004004e1 <+21>:    retq   
End of assembler dump.

Second 第二

(gdb) list
1   int main()
2   {
3       int counter = 0;
4       counter += 10;
5       return 0;
6   }

(gdb) disassemble main
Dump of assembler code for function main:
   0x00000000004004cc <+0>: push   %rbp
   0x00000000004004cd <+1>: mov    %rsp,%rbp
   0x00000000004004d0 <+4>: movl   $0x0,-0x4(%rbp)
   0x00000000004004d7 <+11>:    addl   $0xa,-0x4(%rbp)
=> 0x00000000004004db <+15>:    mov    $0x0,%eax
   0x00000000004004e0 <+20>:    pop    %rbp
   0x00000000004004e1 <+21>:    retq   
End of assembler dump.

So why is "(variable) += (value)" faster than "(variable) = (variable) + (value)" ? 那么,为什么“(变量)+ =(值)”比“(变量)=(变量)+(值)”更快?

It's not faster. 不快。 As you see, the generated assembly is identical. 如您所见,生成的程序集是相同的。 Whoever told you one is faster was making up stories. 谁告诉你一个更快的速度就是在编故事。

As others said, in this case it doesn't matter. 就像其他人所说的,在这种情况下没关系。 However, there are some similar but very different cases: 但是,有一些类似但非常不同的情况:

int *f(void);
(*f()) = (*f()) + 1;
(*f()) += 1;

In the 2nd line, f() is called twice, in the 3rd line just once. 在第二行中, f()被调用两次,在第三行中,仅被调用一次。

int * volatile *p;
**p = **p + 1;
**p += 2;

In the 2nd line, the compiler will read *p twice, assuming it may change between accesses (and you'd be reading one place, writing another). 在第二行中,编译器将读取*p两次,并假设它在两次访问之间可能会发生变化(并且您将读一个地方,写另一个地方)。 In the 3rd, it will read *p once and increment this place. 在第3个中,它将读一次*p并递增该位置。

And if you're feeling naughty: 如果您感到顽皮:

#define a *f()
int a;
a = a + 1;
a++;

Looks almost exactly as in the question, but behaves like my first example. 看起来几乎与问题中的一样,但行为与我的第一个示例类似。

I think you just proved that it is not faster at all for whichever c compiler you are using. 我认为您刚刚证明,无论使用哪种c编译器,它都根本不快。 However, you may have optimizations running during the compile. 但是,您可能在编译过程中运行了优化。 Also, other compilers may not do that the same way. 另外,其他编译器可能不会以相同的方式进行操作。

I think what they meant by "faster" is that its easier to type a += 10 than a = a + 10 . 我认为他们所说的“更快”是指输入a += 10比输入a = a + 10更容易。 Both are completely identical otherwise. 两者都完全相同。

You have to look at this on a compiler by compiler basis, and option by option. 您必须在逐个编译器的基础上并逐个选项地进行研究。 Unoptimized it might generate different code, but at the same time unoptimized is going to likely be much slower even for this single one line of code. 未优化的代码可能会生成不同的代码,但是同时,即使对于这一行代码,未优化的代码也可能会慢得多。 The real answer has to do with the compiler internals which you can see really easy with clang/llvm, but maybe with gcc and others. 真正的答案与编译器内部有关,使用clang / llvm可以很容易地看到编译器的内部,但也许可以与gcc等一起使用。 By the time it generates assembly it is well down the road, compilers tend to have an internal generic code that gets some optimization then the final conversion to assembly/machine code has further target specific optimization. 到了生成汇编的时候,编译器往往会拥有内部通用代码来进行一些优化,然后最终转换为汇编/机器代码将进一步针对特定目标进行优化。 The interesting answer to your question is what does the compiler frontend do with those two subtle different lines of code? 您的问题的有趣答案是,编译器前端如何使用这两行微妙的不同代码行? If not from the very beginning at what point do those two join and become the same result at or on the way to the assembly/machine code output? 如果不是从一开始就不是那一点,那么这两者在汇编/机器代码输出的途中或在什么时候会变成相同的结果?

No. You had incorrect information. 否。您的信息不正确。 Both the instructions take up the same time. 两条指令占用相同的时间。

Both

int a = 0;
a += 10;

and

int a = 0;
a = a + 10;

generate the same assembly code and are having equal speed. 生成相同的汇编代码并且速度相同。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM