Created
December 3, 2014 17:25
-
-
Save simonbyrne/1e4f5234eaa70725c30f to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function rint_llvm(x::Float64) | |
Base.llvmcall("""%x = call double @llvm.rint.f64(double %0) | |
ret double %x""",Float64,(Float64,),x) | |
end | |
function trunc_llvm(x::Float64) | |
Base.llvmcall("""%x = call double @llvm.trunc.f64(double %0) | |
ret double %x""",Float64,(Float64,),x) | |
end | |
# warm up llvmcall: ignore errors | |
rint_llvm(1.0) | |
rint_llvm(1.0) | |
trunc_llvm(1.0) | |
trunc_llvm(1.0) | |
# use "add remainder" trick | |
function round_rem(x::Float64) | |
t = trunc_llvm(x) | |
trunc_llvm(x+(x-t)) | |
end | |
# use "prevfloat(0.5)" trick | |
round_prev(x::Float64) = trunc_llvm(x+copysign(0.49999999999999994,x)) | |
round_rem(1.0) | |
round_rem(1.0) | |
round_prev(1.0) | |
round_prev(1.0) | |
function test_rint_llvm(N) | |
t = 1.0 | |
s = 0.0 | |
for i = 1:N | |
t += eps() | |
s += rint_llvm(t) | |
end | |
s | |
end | |
function test_round_rem(N) | |
t = 1.0 | |
s = 0.0 | |
for i = 1:N | |
t += eps() | |
s += round_rem(t) | |
end | |
s | |
end | |
function test_round_prev(N) | |
t = 1.0 | |
s = 0.0 | |
for i = 1:N | |
t += eps() | |
s += round_prev(t) | |
end | |
s | |
end | |
@time test_rint_llvm(100_000_000); | |
@time test_rint_llvm(100_000_000); | |
@time test_round_rem(100_000_000); | |
@time test_round_rem(100_000_000); | |
@time test_round_prev(100_000_000); | |
@time test_round_prev(100_000_000); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
times after warmup:
Looking at the
@code_native
, only unvectorised (vroundsd
) instructions were used.