[英]Why does this code behave differently if optimizing (-O2, -O3) is used?
[英]What does the compiler do in assembly when optimizing code? ie -O2 flag
因此,當您在編譯C ++時添加優化標志時,它運行得更快,但這是如何工作的? 有人能解釋一下裝配中究竟發生了什么嗎?
這意味着您正在使編譯器在編譯時執行額外的工作/分析,因此您可以在運行時獲得一些額外的寶貴cpu周期的獎勵。 可能最好用一個例子來解釋。
考慮這樣的循環:
const int n = 5;
for (int i = 0; i < n; ++i)
cout << "bleh" << endl;
如果你在沒有優化的情況下編譯它,編譯器將不會為你做任何額外的工作 - 為這段代碼片段生成的程序集可能是比較和跳轉指令的字面翻譯。 (這不是最快的,只是最直接的)
但是,如果編譯WITH優化,編譯器可以很容易地inline
這個循環,因為它知道上限不能改變,因為n
是const
。 (即它可以直接復制重復代碼5次,而不是比較/檢查終止循環條件)。
這是另一個優化函數調用的例子。 以下是我的整個計划:
#include <stdio.h>
static int foo(int a, int b) {
return a * b;
}
int main(int argc, char** argv) {
fprintf(stderr, "%d\n", foo(10, 15));
return 0;
}
如果我在我的x86機器上使用gcc foo.c
編譯此代碼時沒有進行優化,我的程序集如下所示:
movq %rsi, %rax
movl %edi, -4(%rbp)
movq %rax, -16(%rbp)
movl $10, %eax ; these are my parameters to
movl $15, %ecx ; the foo function
movl %eax, %edi
movl %ecx, %esi
callq _foo
; .. about 20 other instructions ..
callq _fprintf
在這里,它沒有優化任何東西。 它用我的常量值加載寄存器並調用我的foo
函數。 但看看我是否用-O2
標志重新編譯:
movq (%rax), %rdi
leaq L_.str(%rip), %rsi
movl $150, %edx
xorb %al, %al
callq _fprintf
編譯器非常聰明,甚至不再調用foo
。 它只是概述了它的回報價值。
在生成程序集之前,大多數優化都發生在編譯器的中間表示中。 您一定要查看Agner Fog的軟件優化資源 。 第1手冊的第8章描述了編譯器使用示例執行的優化。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.