Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
julia> import BenchmarkTools: @btime
julia> @inline _logistic_bounds(x::Float16) = (Float16(-16.64), Float16(7.625))
_logistic_bounds (generic function with 1 method)
julia> @inline _logistic_bounds(x::Float32) = (-103.27893f0, 16.635532f0)
_logistic_bounds (generic function with 2 methods)
julia> @inline _logistic_bounds(x::Float64) = (-744.4400719213812, 36.7368005696771)
_logistic_bounds (generic function with 3 methods)
julia> function logistic_v0(x::Union{Float16, Float32, Float64})
one(x) / (one(x) + exp(-x))
end
logistic_v0 (generic function with 1 method)
julia> function logistic_v1(x::Union{Float16, Float32, Float64})
e = exp(x)
lower, upper = _logistic_bounds(x)
ifelse(
x < lower,
zero(x),
ifelse(
x > upper,
one(x),
e / (one(x) + e)
)
)
end
logistic_v1 (generic function with 1 method)
julia> function logistic_v2(x::Union{Float16, Float32, Float64})
lower, upper = _logistic_bounds(x)
if x < lower
zero(x)
elseif x > upper
one(x)
else
e = exp(x)
e / (one(x) + e)
end
end
logistic_v2 (generic function with 1 method)
julia> @code_llvm logistic_v1(-710.0)
; @ REPL[6]:2 within `logistic_v1'
define double @julia_logistic_v1_17188(double) {
top:
%1 = call double @julia_exp_17189(double %0)
; @ REPL[6]:4 within `logistic_v1'
; ┌ @ float.jl:458 within `<'
%2 = fcmp uge double %0, 0xC0874385446D71C3
; └
; ┌ @ operators.jl:294 within `>'
; │┌ @ float.jl:458 within `<'
%3 = fcmp ule double %0, 0x40425E4F7B2737FA
; └└
; ┌ @ float.jl:401 within `+'
%4 = fadd double %1, 1.000000e+00
; └
; ┌ @ float.jl:407 within `/'
%5 = fdiv double %1, %4
; └
%6 = select i1 %3, double %5, double 1.000000e+00
%7 = select i1 %2, double %6, double 0.000000e+00
ret double %7
}
julia> @code_llvm logistic_v2(-710.0)
; @ REPL[7]:2 within `logistic_v2'
define double @julia_logistic_v2_17190(double) {
top:
; @ REPL[7]:3 within `logistic_v2'
; ┌ @ float.jl:458 within `<'
%1 = fcmp uge double %0, 0xC0874385446D71C3
; └
br i1 %1, label %L4, label %L3
L3: ; preds = %L4, %top
%merge = phi double [ 0.000000e+00, %top ], [ 1.000000e+00, %L4 ]
; @ REPL[7]:4 within `logistic_v2'
ret double %merge
L4: ; preds = %top
; @ REPL[7]:5 within `logistic_v2'
; ┌ @ operators.jl:294 within `>'
; │┌ @ float.jl:458 within `<'
%2 = fcmp ule double %0, 0x40425E4F7B2737FA
; └└
br i1 %2, label %L7, label %L3
L7: ; preds = %L4
; @ REPL[7]:8 within `logistic_v2'
%3 = call double @julia_exp_17189(double %0)
; @ REPL[7]:9 within `logistic_v2'
; ┌ @ float.jl:401 within `+'
%4 = fadd double %3, 1.000000e+00
; └
; ┌ @ float.jl:407 within `/'
%5 = fdiv double %3, %4
; └
ret double %5
}
julia> @code_native logistic_v1(-710.0)
.section __TEXT,__text,regular,pure_instructions
; ┌ @ REPL[6]:2 within `logistic_v1'
pushq %rax
vmovsd %xmm0, (%rsp)
movabsq $"reinterpret;", %rax
callq *%rax
vmovsd (%rsp), %xmm2 ## xmm2 = mem[0],zero
movabsq $4554540192, %rax ## imm = 0x10F78C4A0
; │ @ REPL[6]:4 within `logistic_v1'
; │┌ @ operators.jl:294 within `>'
; ││┌ @ float.jl:458 within `<'
vucomisd (%rax), %xmm2
movabsq $4554540200, %rax ## imm = 0x10F78C4A8
vmovsd (%rax), %xmm1 ## xmm1 = mem[0],zero
; │└└
ja L61
; │┌ @ float.jl within `+'
vaddsd %xmm1, %xmm0, %xmm1
; │└
; │┌ @ float.jl:407 within `/'
vdivsd %xmm1, %xmm0, %xmm1
; └└
; ┌ @ float.jl within `logistic_v1'
L61:
movabsq $4554540208, %rax ## imm = 0x10F78C4B0
; └
; ┌ @ REPL[6]:4 within `logistic_v1'
vcmpnltsd (%rax), %xmm2, %xmm0
vandpd %xmm1, %xmm0, %xmm0
popq %rax
retq
nopw %cs:(%rax,%rax)
nopl (%rax)
; └
julia> @code_native logistic_v2(-710.0)
.section __TEXT,__text,regular,pure_instructions
; ┌ @ REPL[7]:2 within `logistic_v2'
pushq %rbx
vxorps %xmm1, %xmm1, %xmm1
movabsq $4554543632, %rax ## imm = 0x10F78D210
vmovsd (%rax), %xmm2 ## xmm2 = mem[0],zero
; │ @ REPL[7]:3 within `logistic_v2'
; │┌ @ float.jl:458 within `<'
vucomisd %xmm0, %xmm2
; │└
ja L77
movabsq $4554543640, %rbx ## imm = 0x10F78D218
movabsq $4554543648, %rax ## imm = 0x10F78D220
; │ @ REPL[7]:5 within `logistic_v2'
; │┌ @ operators.jl:294 within `>'
; ││┌ @ float.jl:458 within `<'
vucomisd (%rax), %xmm0
; │└└
ja L73
; │ @ REPL[7]:8 within `logistic_v2'
movabsq $"reinterpret;", %rax
callq *%rax
; │ @ REPL[7]:9 within `logistic_v2'
; │┌ @ float.jl:401 within `+'
vaddsd (%rbx), %xmm0, %xmm1
; │└
; │┌ @ float.jl:407 within `/'
vdivsd %xmm1, %xmm0, %xmm0
; │└
popq %rbx
retq
L73:
vmovsd (%rbx), %xmm1 ## xmm1 = mem[0],zero
; │ @ REPL[7]:4 within `logistic_v2'
L77:
vmovaps %xmm1, %xmm0
popq %rbx
retq
nopw %cs:(%rax,%rax)
nopl (%rax)
; └
julia> z = -710.0
-710.0
julia> @btime logistic_v0($z);
0.035 ns (0 allocations: 0 bytes)
julia> @btime logistic_v1($z);
93.639 ns (0 allocations: 0 bytes)
julia> @btime logistic_v2($z);
93.414 ns (0 allocations: 0 bytes)
julia> @btime logistic_v2($z);
91.336 ns (0 allocations: 0 bytes)
julia> @btime logistic_v1($z);
92.003 ns (0 allocations: 0 bytes)
julia> @btime logistic_v0($z);
0.033 ns (0 allocations: 0 bytes)
julia> z = +710.0
710.0
julia> @btime logistic_v0($z);
54.049 ns (0 allocations: 0 bytes)
julia> @btime logistic_v1($z);
0.033 ns (0 allocations: 0 bytes)
julia> @btime logistic_v2($z);
0.034 ns (0 allocations: 0 bytes)
julia> @btime logistic_v2($z);
0.034 ns (0 allocations: 0 bytes)
julia> @btime logistic_v1($z);
0.034 ns (0 allocations: 0 bytes)
julia> @btime logistic_v0($z);
54.050 ns (0 allocations: 0 bytes)
julia> x = rand(10_000_000);
julia> @btime logistic_v0.($x);
81.563 ms (2 allocations: 76.29 MiB)
julia> @btime logistic_v1.($x);
85.935 ms (2 allocations: 76.29 MiB)
julia> @btime logistic_v2.($x);
87.461 ms (2 allocations: 76.29 MiB)
julia> @btime logistic_v2.($x);
86.782 ms (2 allocations: 76.29 MiB)
julia> @btime logistic_v1.($x);
86.505 ms (2 allocations: 76.29 MiB)
julia> @btime logistic_v0.($x);
82.144 ms (2 allocations: 76.29 MiB)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment