Opened 6 years ago

Closed 6 years ago

Last modified 6 years ago

#2251 closed bug (fixed)

Missing conversion rules for realToFrac causing slowdowns in Int->Double conversions

Reported by: dons Owned by: dons
Priority: normal Milestone:
Component: Runtime System Version: 6.8.2
Keywords: floating point, performance Cc: dons@…
Operating System: Unknown/Multiple Architecture: Unknown/Multiple
Type of failure: Difficulty: Unknown
Test Case: Blocked By:
Blocking: Related Tickets:

Description

GHC.Real and GHC.Float currently have:

-- | general coercion from integral types
fromIntegral :: (Integral a, Num b) => a -> b
fromIntegral = fromInteger . toInteger

{-# RULES
"fromIntegral/Int->Int" fromIntegral = id :: Int -> Int
    #-}

-- | general coercion to fractional types
realToFrac :: (Real a, Fractional b) => a -> b
realToFrac = fromRational . toRational

{-# RULES
"realToFrac/Int->Int" realToFrac = id :: Int -> Int
    #-}

But these avoid some primops that can make these conversions
more efficient.

{-# RULES
"realToFrac/Int->Double" realToFrac = i2d :: Int -> Double
#-}

int2Double :: Int -> Double
int2Double   (I# x) = D# (int2Double# x)

A rule to use the in2Double# primop over realToFrac directly, improves
the running time of this program:

import Data.Array.Parallel.Unlifted
main = do
    let c = replicateU n (2::Double)
        a = mapU realToFrac (enumFromToU 0 (n-1) ) :: UArr Double
    print (sumU (zipWithU (*) c a))

From 113 seconds, to 0.194s! A massive speedup.

We should fill out the rules here with at least those for which GHC
has primitives:

{-# RULES
"realToFrac/Int->Double" realToFrac = int2Double :: Int -> Double
"realToFrac/Int->Float"  realToFrac = int2Float  :: Int -> Float
  #-}

to the realToFrac and fromIntegral rules in GHC.Float

Change History (5)

comment:1 Changed 6 years ago by simonpj

  • Difficulty set to Unknown

Thanks Don. Would you care to offer a patch? (Don't forget to include comments that explain how big the performance improvement is; I find that giving a little program in that comment (as you do above) is a great way to capture the idea.)

I gather that when you say "...at least those for which GHC has primitives" you mean that there are some important ones missing. If so, propose away.

Simon

comment:2 Changed 6 years ago by dons

  • Resolution set to fixed
  • Status changed from new to closed

I've pushed a patch adding the rules for Int->Double and Int->Float.

See:

http://www.haskell.org/pipermail/cvs-libraries/2008-April/008493.html

comment:3 Changed 6 years ago by simonpj

Thanks! I've found that comments in source files are more often read than those in patch messages, so I've transferred some of your comments into the source file itself.

Simon

comment:4 Changed 6 years ago by simonmar

  • Architecture changed from Unknown to Unknown/Multiple

comment:5 Changed 6 years ago by simonmar

  • Operating System changed from Unknown to Unknown/Multiple
Note: See TracTickets for help on using tickets.