I speed up “bool ^ float” and “float ^ bool”.
Сan you help me to know how it works on other processors ?
Need a print of this thing:
module M
using BenchmarkTools, Test, InteractiveUtils
println("**", rstrip(Sys.cpu_info()[1].model), "**")
println("**Julia-",VERSION,"**\n")
println("```")
#
pow_native(x::X, y::Y) where {X,Y} = x ^ y
#
pow_fast(x::Bool, y::T) where T <: AbstractFloat = ifelse(x | iszero(y), T(1) , ifelse(isnan(y), T(NaN), ifelse(signbit(y), T(Inf), T(0))));
pow_fast(x::Bool, y::BigFloat) = big(ifelse(x | iszero(y), 1.0 , ifelse(isnan(y), NaN, ifelse(signbit(y), Inf, 0.0))));
pow_fast(x::T, y::Bool) where T <: AbstractFloat = y ? copy(x) : T(1)
pow_fast(x::BigFloat, y::Bool) = y ? x : big(1.0)
# test data
function get_test_data1(::Type{T}) where T <: AbstractFloat
n = 10000
m = n ÷ 100 # for special values of the same type NaN, -Inf ...
r = zeros(T, n) # for result
x = rand(Bool, n)
y = (T <: BigFloat ? big.(randn(Float64, n)) : randn(T, n)) .^ 111
y[rand(1:n, m)] .= T(NaN)
y[rand(1:n, m)] .= -T(Inf)
y[rand(1:n, m)] .= T(Inf)
y[rand(1:n, m)] .= nextfloat(-T(Inf))
y[rand(1:n, m)] .= prevfloat(T(Inf))
y[rand(1:n, m)] .= T(0)
y[rand(1:n, m)] .= -T(0)
return n, r, x, y
end
function get_test_data2(::Type{T}) where T <: AbstractFloat
n = 10000
m = n ÷ 100 # for special values of the same type NaN, -Inf ...
r = zeros(T, n) # for result
x = (T <: BigFloat ? big.(randn(Float64, n)) : randn(T, n)) .^ 111
y = rand(Bool, n)
x[rand(1:n, m)] .= T(NaN)
x[rand(1:n, m)] .= -T(Inf)
x[rand(1:n, m)] .= T(Inf)
x[rand(1:n, m)] .= nextfloat(-T(Inf))
x[rand(1:n, m)] .= prevfloat(T(Inf))
x[rand(1:n, m)] .= T(0)
x[rand(1:n, m)] .= -T(0)
return n, r, x, y
end
# tests
@testset verbose = true "Tests" begin
@testset verbose = false "Fast `bool ^ float`" begin
for Flt in subtypes(AbstractFloat)
@testset verbose = true " $Flt" begin
n, r, x, y = get_test_data1(Flt)
@testset "$pow_fast" begin
for i = 1 : n
r_native = pow_native(x[i],y[i])
r_fast = pow_fast(x[i],y[i])
# big(1.0) !== big(1.0), NaN != NaN
@test r_native == r_fast ? true :
isnan(r_native) & isnan(r_fast) ? true : false
end
end
end
end
end
@testset verbose = false "Fast `float ^ bool`" begin
for Flt in subtypes(AbstractFloat)
@testset verbose = true " $Flt" begin
n, r, x, y = get_test_data2(Flt)
@testset "$pow_fast" begin
for i = 1 : n
r_native = pow_native(x[i],y[i])
r_fast = pow_fast(x[i],y[i])
# big(1.0) !== big(1.0), NaN != NaN
@test r_native == r_fast ? true :
isnan(r_native) & isnan(r_fast) ? true : false
end
end
end
end
end
end;
# benchmarks
f!(f,r,x,y,n) = for i = 1 : n
r[i] = f(x[i], y[i])
end;
println("\nFast `bool ^ float` benchmark (1 - native 2 - fast):")
for Flt in subtypes(AbstractFloat)
n, r, x, y = get_test_data1(Flt)
println(" $Flt:")
@btime f!($pow_native,$r,$x,$y,$n)
@btime f!($pow_fast,$r,$x,$y,$n)
end
println("\nFast `float ^ bool` benchmark (1 - native 2 - fast):")
for Flt in subtypes(AbstractFloat)
n, r, x, y = get_test_data2(Flt)
println(" $Flt:")
@btime f!($pow_native,$r,$x,$y,$n)
@btime f!($pow_fast,$r,$x,$y,$n)
end
println("```")
end;