c ++循环编译器优化

Gui*_*e07 1 c++ optimization loops

double var = 0.;
for(int i = 0; i < 1000000 ; i++)
{
    var += sqrt(2.0);
}
std::cout << var << std::endl;
Run Code Online (Sandbox Code Playgroud)

在MSVC2012下,是否有可能在优化开启的情况下,sqrt(2.0)将被调用的值替换,而不是称之为1*10 ^ 6次?

Asm看起来像这样,不确定它的解释:

; Line 6
    push    ebp
    mov ebp, esp
    sub esp, 84                 ; 00000054H
    push    ebx
    push    esi
    push    edi
; Line 8
    movsd   xmm0, QWORD PTR __real@0000000000000000
    movsd   QWORD PTR _var$[ebp], xmm0
; Line 9
    mov DWORD PTR _i$1[ebp], 0
    jmp SHORT $LN3@main
$LN2@main:
    mov eax, DWORD PTR _i$1[ebp]
    add eax, 1
    mov DWORD PTR _i$1[ebp], eax
$LN3@main:
    cmp DWORD PTR _i$1[ebp], 1000000        ; 000f4240H
    jge SHORT $LN1@main
; Line 11
    sub esp, 8
    movsd   xmm0, QWORD PTR __real@4000000000000000
    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 $LN2@main
Run Code Online (Sandbox Code Playgroud)

编辑:

对不起上面是调试版....

; Line 7
    push    ebp
    mov ebp, esp
    and esp, -8                 ; fffffff8H
; Line 11
    movsd   xmm0, QWORD PTR __real@4000000000000000
    call    __libm_sse2_sqrt_precise
    movsd   xmm2, QWORD PTR ?var@@3NA
    mov eax, 1000000                ; 000f4240H
$LL3@main:
    movapd  xmm1, xmm0
    addsd   xmm2, xmm1
    dec eax
    jne SHORT $LL3@main
    movsd   QWORD PTR ?var@@3NA, xmm2
; Line 13
    mov esp, ebp
    pop ebp
    ret 0
Run Code Online (Sandbox Code Playgroud)

zwo*_*wol 5

如果我正确读取汇编转储,编译器会sqrt在调试版本中保留循环,并在优化版本中将其移出.但它可能更具攻击性; 您展示的代码可以合法地优化

std::cout << "1414213.56238\n" << std::flush;
Run Code Online (Sandbox Code Playgroud)

AS-如果规则允许编译器做任何事情不改变程序的"看得见的行为" -而执行时间不能算作观察到的行为.还允许编译器"知道"所有标准库函数在此基础上执行和优化的内容.