Dim performance has regressed by 14% vs 1.9 on amd64.
Current pure go version of Dim is faster and,
what is even more important for performance, is inlinable, so
instead of tweaking asm implementation, just remove it.
I had to update BenchmarkDim, because it was simply reloading
constant(answer) in a loop.
Perf data below:
name old time/op new time/op delta
Dim-6 6.79ns ± 0% 1.60ns ± 1% -76.39% (p=0.000 n=7+10)
If I modify benchmark to be the same as in this CL results are even better:
name old time/op new time/op delta
Dim-6 10.2ns ± 0% 1.6ns ± 1% -84.27% (p=0.000 n=8+10)
Updates #21913
Change-Id: I00e23c8affc293531e1d9f0e0e49f3a525634f53
Reviewed-on: https://go-review.googlesource.com/80695
Run-TryBot: Ilya Tocar <ilya.tocar@intel.com>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
func BenchmarkDim(b *testing.B) {
x := 0.0
for i := 0; i < b.N; i++ {
- x = Dim(10, 3)
+ x = Dim(GlobalF, x)
}
GlobalF = x
}
// Dim(+Inf, +Inf) = NaN
// Dim(-Inf, -Inf) = NaN
// Dim(x, NaN) = Dim(NaN, x) = NaN
-func Dim(x, y float64) float64
-
-func dim(x, y float64) float64 {
+func Dim(x, y float64) float64 {
// The special cases result in NaN after the subtraction:
// +Inf - +Inf = NaN
// -Inf - -Inf = NaN
#include "textflag.h"
-TEXT ·Dim(SB),NOSPLIT,$0
- JMP ·dim(SB)
-
TEXT ·Max(SB),NOSPLIT,$0
JMP ·max(SB)
#define NaN 0x7FF8000000000001
#define NegInf 0xFFF0000000000000
-// func Dim(x, y float64) float64
-TEXT ·Dim(SB),NOSPLIT,$0
- // (+Inf, +Inf) special case
- MOVQ x+0(FP), BX
- MOVQ y+8(FP), CX
- MOVQ $PosInf, AX
- CMPQ AX, BX
- JNE dim2
- CMPQ AX, CX
- JEQ bothInf
-dim2: // (-Inf, -Inf) special case
- MOVQ $NegInf, AX
- CMPQ AX, BX
- JNE dim3
- CMPQ AX, CX
- JEQ bothInf
-dim3: // (NaN, x) or (x, NaN)
- MOVQ $~(1<<63), DX
- MOVQ $PosInf, AX
- ANDQ DX, BX // x = |x|
- CMPQ AX, BX
- JLT isDimNaN
- ANDQ DX, CX // y = |y|
- CMPQ AX, CX
- JLT isDimNaN
-
- MOVSD x+0(FP), X0
- SUBSD y+8(FP), X0
- MOVSD $(0.0), X1
- MAXSD X1, X0
- MOVSD X0, ret+16(FP)
- RET
-bothInf: // Dim(-Inf, -Inf) or Dim(+Inf, +Inf)
-isDimNaN:
- MOVQ $NaN, AX
- MOVQ AX, ret+16(FP)
- RET
-
// func ·Max(x, y float64) float64
TEXT ·Max(SB),NOSPLIT,$0
// +Inf special cases
#include "textflag.h"
-TEXT ·Dim(SB),NOSPLIT,$0
- B ·dim(SB)
-
TEXT ·Min(SB),NOSPLIT,$0
B ·min(SB)
#define NaN 0x7FF8000000000001
#define NegInf 0xFFF0000000000000
-// func Dim(x, y float64) float64
-TEXT ·Dim(SB),NOSPLIT,$0
- // (+Inf, +Inf) special case
- MOVD $PosInf, R0
- MOVD x+0(FP), R1
- MOVD y+8(FP), R2
- CMP R0, R1
- BNE dim2
- CMP R0, R2
- BEQ bothInf
-dim2: // (-Inf, -Inf) special case
- MOVD $NegInf, R0
- CMP R0, R1
- BNE dim3
- CMP R0, R2
- BEQ bothInf
-dim3: // normal case
- FMOVD R1, F0
- FMOVD R2, F1
- FMOVD $0.0, F2
- FSUBD F1, F0
- FMAXD F0, F2, F0
- FMOVD F0, ret+16(FP)
- RET
-bothInf:
- MOVD $NaN, R0
- MOVD R0, ret+16(FP)
- RET
-
// func ·Max(x, y float64) float64
TEXT ·Max(SB),NOSPLIT,$0
// +Inf special cases
TEXT ·Atanh(SB),NOSPLIT,$0
JMP ·atanh(SB)
-TEXT ·Dim(SB),NOSPLIT,$0
- JMP ·dim(SB)
-
TEXT ·Min(SB),NOSPLIT,$0
JMP ·min(SB)
TEXT ·Atanh(SB),NOSPLIT,$0
JMP ·atanh(SB)
-TEXT ·Dim(SB),NOSPLIT,$0
- JMP ·dim(SB)
-
TEXT ·Min(SB),NOSPLIT,$0
JMP ·min(SB)
TEXT ·Atanh(SB),NOSPLIT,$0
BR ·atanh(SB)
-TEXT ·Dim(SB),NOSPLIT,$0
- BR ·dim(SB)
-
TEXT ·Min(SB),NOSPLIT,$0
BR ·min(SB)
#include "textflag.h"
-TEXT ·Dim(SB),NOSPLIT,$0
- BR ·dim(SB)
-
TEXT ·Exp2(SB),NOSPLIT,$0
BR ·exp2(SB)