我编写了一个代码,在C++中什么都不做
void main(void){
}
Run Code Online (Sandbox Code Playgroud)
和大会.
.global _start
.text
_start:
mov $60, %rax
xor %rdi, %rdi
syscall
Run Code Online (Sandbox Code Playgroud)
我编译C代码并编译和链接汇编代码.我用time命令比较了两个可执行文件.
部件
time ./Assembly
real 0m0.001s
user 0m0.000s
sys 0m0.000s
Run Code Online (Sandbox Code Playgroud)
C
time ./C
real 0m0.002s
user 0m0.000s
sys 0m0.000s
Run Code Online (Sandbox Code Playgroud)
汇编速度比C快两倍.我反汇编代码,在汇编代码中,只有四行代码(相同).在C代码中,有大量不必要的代码用于将main链接到_start.主要有四行代码,其中三行代表不可能(你不能从函数博客外部访问函数的变量)从' block ' 外部访问' local '(如函数变量)变量(像功能块一样).
push %rbp ; push base pointer.
mov %rsp, %rbp ; copy value of stack pointer to base pointer, stack pointer is using for saving variables.
pop %rbp ; 'local' variables are removed, because we pop the base pointer
retq ; ?
Run Code Online (Sandbox Code Playgroud)
那是什么原因?
tem*_*def 13
执行您编写的程序核心所需的时间非常小.图中它由三个或四个汇编代码组成,并且在几千兆赫兹的情况下运行只需要几纳秒.这是一个很短的时间,它远远低于程序的检测阈值time,其分辨率以毫秒为单位测量(请记住,毫秒是一纳秒的百万分之一!)所以在这个意义上,我会非常小心判断一个程序的运行时间是"另一个程序"的"两倍"; 你的计时器的分辨率不够高,不能说肯定.你可能只是看到噪音条款.
但是,您的问题是,如果没有任何事情发生,那么就会有所有这些自动生成的代码.答案是"这取决于".由于没有打开优化,大多数编译器会生成汇编代码,忠实地模拟您编写的程序,可能会执行超出必要的工作.由于大多数C和C++函数,你实际上会有代码执行某些操作,需要局部变量等,编译器在函数的开头和结尾发出代码来设置堆栈和框架时不会太错指针适当地支持那些变量.随着优化达到最大值,优化编译器可能足够聪明,可以注意到这不是必需的并且删除该代码,但这不是必需的.
原则上,一个完美的编译器总是可以发出最快的代码,但事实证明,构建一个总能做到这一点的编译器是不可能的(这与诸如停止问题的不可判断性之类的事情有关).因此,有些人认为生成的代码会很好 - 甚至很好 - 但不是最优的.但是,这是一个权衡.是的,代码可能没有它可能的那么快,但是通过使用C和C++这样的语言,可以以一种易于阅读,易于编写的方式编写大型复杂程序(与汇编相比).易于维护.我们对性能的轻微影响是好的,因为在实践中它并不太糟糕,而且大多数优化编译器都足以使价格可以忽略不计(如果优化编译器找到比人类更好的方法来解决问题,那么甚至是负面的!)
总结一下:
您的计时机制可能不足以得出您正在做出的结论.你需要一个更高精度的计时器.
为简单起见,编译器经常生成不必要的代码.优化编译器通常会删除该代码,但并不总是如此.
由于易于开发,我们可以在原始运行时方面支付使用更高级语言的成本.实际上,使用具有良好优化编译器的高级语言实际上可能是一个净胜利,因为它卸载了优化复杂性.
| 归档时间: |
|
| 查看次数: |
690 次 |
| 最近记录: |