【发布时间】:2012-12-11 02:14:36
【问题描述】:
double var = 0.;
for(int i = 0; i < 1000000 ; i++)
{
var += sqrt(2.0);
}
std::cout << var << std::endl;
在MSVC2012下,是否有可能在开启优化的release下,sqrt(2.0)会被call的值代替,而不是调用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
编辑:
对不起,上面是调试版本....
; 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
【问题讨论】:
-
可能吗?是的,当然!为什么不呢?
-
“有可能吗?” - 是的。 “会吗?” - 我不知道。看看组装吧。
-
看起来它并没有优化那个特定的东西,不,但是你在编译优化吗?
-
好问题。我猜编译器不知道 sqrt 将始终使用相同的参数获得相同的值。我不知道如何解决它
-
如果 OP 开启了激进的浮点优化,结果可能会有所不同——我不知道 MSVC 怎么称呼那个特定的切换,但它肯定有一些相当于 GCC 的
-ffast-math。
标签: c++ optimization loops