繁体   English   中英

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

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

我听到很多人说

int a = 0;
a += 10;

比...快

int a = 0;
a = a + 10;

这是为什么? 我用gdb调试了它,它是完全相同的指令。

gdb:

第一

(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.

第二

(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.

那么,为什么“(变量)+ =(值)”比“(变量)=(变量)+(值)”更快?

不快。 如您所见,生成的程序集是相同的。 谁告诉你一个更快的速度就是在编故事。

就像其他人所说的,在这种情况下没关系。 但是,有一些类似但非常不同的情况:

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

在第二行中, f()被调用两次,在第三行中,仅被调用一次。

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

在第二行中,编译器将读取*p两次,并假设它在两次访问之间可能会发生变化(并且您将读一个地方,写另一个地方)。 在第3个中,它将读一次*p并递增该位置。

如果您感到顽皮:

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

看起来几乎与问题中的一样,但行为与我的第一个示例类似。

我认为您刚刚证明,无论使用哪种c编译器,它都根本不快。 但是,您可能在编译过程中运行了优化。 另外,其他编译器可能不会以相同的方式进行操作。

我认为他们所说的“更快”是指输入a += 10比输入a = a + 10更容易。 两者都完全相同。

您必须在逐个编译器的基础上并逐个选项地进行研究。 未优化的代码可能会生成不同的代码,但是同时,即使对于这一行代码,未优化的代码也可能会慢得多。 真正的答案与编译器内部有关,使用clang / llvm可以很容易地看到编译器的内部,但也许可以与gcc等一起使用。 到了生成汇编的时候,编译器往往会拥有内部通用代码来进行一些优化,然后最终转换为汇编/机器代码将进一步针对特定目标进行优化。 您的问题的有趣答案是,编译器前端如何使用这两行微妙的不同代码行? 如果不是从一开始就不是那一点,那么这两者在汇编/机器代码输出的途中或在什么时候会变成相同的结果?

否。您的信息不正确。 两条指令占用相同的时间。

int a = 0;
a += 10;

int a = 0;
a = a + 10;

生成相同的汇编代码并且速度相同。

暂无
暂无

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

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