2012-12-24 143 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允许编译器做任何不改变“观察行为”的程序 - 以及执行时间不能算作观察到的行为。编译器还可以“知道”所有标准库函数的功能,并在此基础上进行优化。