2012-12-24 144 views
1
double var = 0.; 
for(int i = 0; i < 1000000 ; i++) 
{ 
    var += sqrt(2.0); 
} 
std::cout << var << std::endl; 

在MSVC2012,是有可能,根據與優化導通,SQRT(2.0)的釋放將被調用的值來代替,而不是把它稱爲1 * 10^6次?C++循環的編譯器優化

ASM像她那樣,不知道它的解釋:

; Line 6 
    push ebp 
    mov ebp, esp 
    sub esp, 84     ; 00000054H 
    push ebx 
    push esi 
    push edi 
; Line 8 
    movsd xmm0, QWORD PTR [email protected] 
    movsd QWORD PTR _var$[ebp], xmm0 
; Line 9 
    mov DWORD PTR _i$1[ebp], 0 
    jmp SHORT [email protected] 
[email protected]: 
    mov eax, DWORD PTR _i$1[ebp] 
    add eax, 1 
    mov DWORD PTR _i$1[ebp], eax 
[email protected]: 
    cmp DWORD PTR _i$1[ebp], 1000000  ; 000f4240H 
    jge SHORT [email protected] 
; Line 11 
    sub esp, 8 
    movsd xmm0, QWORD PTR [email protected] 
    movsd QWORD PTR [esp], xmm0 
    call _sqrt 
    add esp, 8 
    fstp QWORD PTR tv85[ebp] 
    movsd xmm0, QWORD PTR tv85[ebp] 
    addsd xmm0, QWORD PTR _var$[ebp] 
    movsd QWORD PTR _var$[ebp], xmm0 
; Line 12 
    jmp SHORT [email protected] 

編輯:

抱歉上面的調試版本....

; Line 7 
    push ebp 
    mov ebp, esp 
    and esp, -8     ; fffffff8H 
; Line 11 
    movsd xmm0, QWORD PTR [email protected] 
    call __libm_sse2_sqrt_precise 
    movsd xmm2, QWORD PTR [email protected]@3NA 
    mov eax, 1000000    ; 000f4240H 
[email protected]: 
    movapd xmm1, xmm0 
    addsd xmm2, xmm1 
    dec eax 
    jne SHORT [email protected] 
    movsd QWORD PTR [email protected]@3NA, xmm2 
; Line 13 
    mov esp, ebp 
    pop ebp 
    ret 0 
+0

你有MSVS2012嗎? –

+0

只有快遞版 – Guillaume07

+0

可能嗎?是的,當然!爲什麼不? –

回答

1

這顯然被稱爲預計:

movsd QWORD PTR [esp], xmm0 
call _sqrt 

編輯: 我能想到的,以強制編譯器不優化了通話,而無需改變優化參數的一種方法,是從stdin在通過在命令行上傳遞給sqrt()值或閱讀:

double var = 0.; 
double x; 
cin >> x; 
for(int i = 0; i < 1000000 ; i++) { 
    var += sqrt(x); 
} 

我認爲,應該使人們無法優化呼叫,因爲該值在編譯時不知道,循環仍可能優化,但你可以通過計數器的值了。

+0

OP可能試圖對'sqrt'進行基準測試。 – zwol

+0

@ Guillaume07哦,我看,更新。 – iabdalkader

5

如果我正確讀取組件轉儲,編譯器在調試版本的循環左sqrt,並在優化建設再搬出來。但它可能更具侵略性;告訴你的代碼可以合法進行優化,以

std::cout << "1414213.56238\n" << std::flush; 

as-if rule允許編譯器做任何不改變「觀察行爲」的程序 - 以及執行時間不能算作觀察到的行爲。編譯器還可以「知道」所有標準庫函數的功能,並在此基礎上進行優化。