haskell - What's the fastest way to calculate a bit mask from the sign of an Int? -
haskell - What's the fastest way to calculate a bit mask from the sign of an Int? -
yes, know insane question. please don't bother asking if need know reply or if "my" problem is. thanks.
there times when next function nice have:
isneg# :: int# -> int# isneg# x | x <# 0# = -1# | otherwise = 0#
for example, used this:
cc# f x y = word2int# (f (int2word# x) (int2word# y)) andi# x y = cc# and# x y xori# x y = cc# xor# x y ori# x y = cc# or# x y ifnegfstelsesnd# :: int# -> int# -> int# ifnegfstelsesnd# x y = case isneg# x of n -> ori# (andi# n y) (xori# n y)
when above definition of isneg
compiled using ghc 7.6.3 -fllvm , -o2, produces
# bb#0: # %ci4 movq (%rbp), %rax testq %r14, %r14 js .lbb0_2 # bb#1: # %nid xorl %ebx, %ebx jmpq *%rax # tailcall .lbb0_2: # %cic movq $-1, %rbx jmpq *%rax # tailcall
the problem js
conditional jump, , these seem considered efficiency problems tight loops (where unboxed, etc). alternative write
isneg# :: int# -> int# isneg# x = uncheckedishiftra# x (intsize# -# 1#) intsize# = case bitsize (undefined::int) of i# size -> size
this produces
# bb#0: # %cny sarq $63, %r14 movq (%rbp), %rax movq %r14, %rbx jmpq *%rax # tailcall
this straightforward, i'm given understand shifts (sarq
) relatively slow operations.
another alternative seems reasonable is
isneg2# :: int# -> int# isneg2# x = negateint# ( datatotag# (x <# 0#) )
this, sadly, produces utterly horrible code that's not worth pasting here.
the question is there improve way?would upgrading ghc 7.8.2 , rewriting lastly definition as
isneg2# x = negateint# (x <# 0#) -- (note: edited right before error)
to match new types give wonderful? can't test because don't have ghc 7.8.2.
the type of prims have changed since ghc 7.6.3. example, comparing no longer results in boolean. means isneg#
function should instead read:
isneg# :: int# -> int# isneg# x = negateint# (x <# 0#)
this produces (7.8.2, -o2):
_cmj: testq %r14,%r14 setl %al movzbl %al,%ebx negq %rbx jmp *(%rbp)
edit: , llvm code includes sar
instruction (not sarq
oddly) if bothers reason perhaps should avoid llvm.
haskell integer-arithmetic
Comments
Post a Comment