Sto sperimentando l'assemblaggio generato e ho trovato una cosa interessante. Ci sono due funzioni che eseguono un calcolo identico. L'unica differenza tra loro è il modo in cui i risultati vengono sommati.Differenze dure nell'assemblaggio generato di confronti a virgola mobile < and > =
#include <cmath>
double func1(double x, double y)
{
double result1;
double result2;
if (x*x < 0.0) result1 = 0.0;
else
{
result1 = x*x+x+y;
}
if (y*y < 0.0) result2 = 0.0;
else
{
result2 = y*y+y+x;
}
return (result1 + result2) * 40.0;
}
double func2(double x, double y)
{
double result = 0.0;
if (x*x >= 0.0)
{
result += x*x+x+y;
}
if (y*y >= 0.0)
{
result += y*y+y+x;
}
return result * 40.0;
}
Il complesso generato da x86 clang 3,7 con -O2
interruttore gcc.godbolt.org è ancora molto diverso e inaspettato. (Compilazione sui risultati del GCC in assemblaggio simile)
.LCPI0_0:
.quad 4630826316843712512 # double 40
func1(double, double): # @func1(double, double)
movapd %xmm0, %xmm2
mulsd %xmm2, %xmm2
addsd %xmm0, %xmm2
addsd %xmm1, %xmm2
movapd %xmm1, %xmm3
mulsd %xmm3, %xmm3
addsd %xmm1, %xmm3
addsd %xmm0, %xmm3
addsd %xmm3, %xmm2
mulsd .LCPI0_0(%rip), %xmm2
movapd %xmm2, %xmm0
retq
.LCPI1_0:
.quad 4630826316843712512 # double 40
func2(double, double): # @func2(double, double)
movapd %xmm0, %xmm2
movapd %xmm2, %xmm4
mulsd %xmm4, %xmm4
xorps %xmm3, %xmm3
ucomisd %xmm3, %xmm4
xorpd %xmm0, %xmm0
jb .LBB1_2
addsd %xmm2, %xmm4
addsd %xmm1, %xmm4
xorpd %xmm0, %xmm0
addsd %xmm4, %xmm0
.LBB1_2:
movapd %xmm1, %xmm4
mulsd %xmm4, %xmm4
ucomisd %xmm3, %xmm4
jb .LBB1_4
addsd %xmm1, %xmm4
addsd %xmm2, %xmm4
addsd %xmm4, %xmm0
.LBB1_4:
mulsd .LCPI1_0(%rip), %xmm0
retq
func1
compila a un assemblaggio senza rami, che coinvolge molto meno di quanto le istruzioni func2
. quindi func2
dovrebbe essere molto più lento di func1
.
Qualcuno può spiegare questo comportamento?
La differenza più ovvia è che l'ottimizzatore sa 'x * x <0.0' può essere ottimizzato per' false' ma non sa 'x * x> = 0.0' può essere ottimizzato per' true'. Nell'osservare un sacco di assembly ottimizzati da diversi compilatori, non ho mai visto alcun modello sano di quello che gli ottimizzatori fanno o non capiscono. – JSF