Skip to content

Instantly share code, notes, and snippets.

@eruffaldi
Last active December 30, 2018 11:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save eruffaldi/0c05e1539f14b4c3d68779f622635839 to your computer and use it in GitHub Desktop.
Save eruffaldi/0c05e1539f14b4c3d68779f622635839 to your computer and use it in GitHub Desktop.
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
Copy link
Author

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