Skip to content

Instantly share code, notes, and snippets.

@eruffaldi eruffaldi/cf32.jl
Last active Dec 30, 2018

Embed
What would you like to do?
Julia cf32
function s64toc64(a::Int64)::Int64
return a < 0 ? -(a & 9223372036854775807) : a;
end
function c64tos64(a::Int64)::Int64
return a < 0 ? ((-a) | -9223372036854775808) : a;
end
function s64toc64BL(a::Int64)::Int64
return a ⊻ ((a ⊻ (-(a& 9223372036854775807))) & (a >> 63));
end
function c64tos64BL(a::Int64)::Int64
return a ⊻ ((a ⊻ (-a |-9223372036854775808)) & (a >> 63));
end
function s32toc32(a::Int32)::Int32
return a < 0 ? -(a & 2147483647) : a; # 0x7FFFFFFF is unsigned
end
function c32tos32(a::Int32)::Int32
return a < 0 ? (-a | -2147483648) : a; # 0x80000000 is unsigned
end
function s32toc32BL(a::Int32)::Int32
return a ⊻ ((a ⊻ (-(a & 2147483647))) & (a >> 31));
end
function c32tos32BL(a::Int32)::Int32
return a ⊻ ((a ⊻ (-a | -2147483648)) & (a >> 31));
end
function s16toc16(a::Int16)::Int16
return a < 0 ? -(a & 32767) : a;
end
function c16tos16(a::Int16)::Int16
return a < 0 ? (-a) | -32768 : a;
end
function s16toc16BL(a::Int16)::Int16
return a ⊻ ((a ⊻ (-(a & 32767))) & (a >> 15));
end
function c16tos16BL(a::Int16)::Int16
return a ⊻ ((a ⊻ (-a | -32768)) & (a >> 15));
end
function s32tosb16(a::UInt32)::UInt16
# extract [s(1) exponent(8) fraction(7)]
return UInt16((a>>16)&0xFFFF)
end
function sb16toss32(a::UInt16)::UInt32
return UInt32(a) << 16
end
function approxb16(a::Float32)::Float32
return reinterpret(Float32,sb16toss32(s32tosb16(reinterpret(UInt32,a))))
end
function approxb16fast(a::Float32)::Float32
function cut(a::UInt32)::UInt32
return a & 0xFFFF0000
end
return reinterpret(Float32,cut.(reinterpret(UInt32,a)))
end
af = rand(Float32, 2000)*10 .* -5;
ai = reinterpret(UInt32,af);
ahh = s32tosb16.(ai)
afb = reinterpret(Float32,sb16toss32.(ahh))
using Statistics
d = abs.(afb.-af)
println("mean delta:",mean(d)," std delta:",std(d)," max delta:",maximum(d))
# compare branchless against branching version
af = rand(Float32, 2000)*10 .* -5;
ai = reinterpret(Int32,af);
for i=1:10
println("iter")
@time ac = s32toc32.(ai);
@time acBL = s32toc32BL.(ai);
@time as = c32tos32.(ac);
@time asBL = c32tos32BL.(acBL);
afb = reinterpret(Float32,as);
afbBL = reinterpret(Float32,asBL);
println(af == afb)
println(af == afbBL)
end
# float version, not an advantage
af = rand(Float32, 20000)*10 .* -5;
ai = reinterpret(Int32,af);
bf = rand(Float32, 20000)*10 .* -5;
bi = reinterpret(Int32,bf);
@time ac = s32toc32.(ai);
@time bc = s32toc32.(bi);
println((af .< bf) == (ac .< bc))
for i=1:10
println("iter")
@time af .< bf
@time ac .< bc
end
# double version, not an advantage
af = rand(Float64, 20000)*10 .* -5;
ai = reinterpret(Int64,af);
bf = rand(Float64, 20000)*10 .* -5;
bi = reinterpret(Int64,bf);
@time ac = s64toc64.(ai);
@time bc = s64toc64.(bi);
println((af .< bf) == (ac .< bc))
for i=1:10
println("iter")
@time af .< bf
@time ac .< bc
end
# half version, advantage because it sw based
af = rand(Float16, 20000)*10 .* -5;
ai = reinterpret(Int16,af);
bf = rand(Float16, 20000)*10 .* -5;
bi = reinterpret(Int16,bf);
@time ac = s16toc16.(ai);
@time bc = s16toc16.(bi);
println((af .< bf) == (ac .< bc))
for i=1:10
println("iter")
@time af .< bf
@time ac .< bc
end
@eruffaldi

This comment has been minimized.

Copy link
Owner Author

commented Dec 30, 2018

Second revision added BFLOAT16
Third revision introduced signed constants

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.