FFI Bindings to Libraries using GMP
Benedikt Huber
benjovi at gmx.net
Fri Sep 28 07:41:59 EDT 2007
Am 18.09.2007 um 05:49 schrieb Peter Tanski:
> The best solution would be to revamp the way Integer types are
> implemented, so when possible they are mutable under the hood, much
> like using the binary += instead of the ternary +. Enumerations
> like the test in [1], below, would not be mutable unless there were
> some information such as a good consumer function that indicated
> the intermediate values were only temporarily necessary.
I'm not sure if I understand this correctly;
Do you want to expose an unsafe/IO interface for destructive Integer
manipulation ?
> The OpenSSL library is not GPL compatible, so there would be
> licensing problems for GPL'd system distributions; it is also
> relatively slow, though it does have a noticeably constant curve
> for exponential functions.
Maybe you should add a note to
http://hackage.haskell.org/trac/ghc/wiki/ReplacingGMPNotes/
PerformanceMeasurements.
The statistics suggest that the OpenSSL BN has comparable performance
to the GMP, especially for smaller numbers.
Some note about the (very confusing) licensing issues regarding
OpenSSL would also be nice.
>> [1] Simple Performance Test on (ghc-darwin-i386-6.6.1):
> Malloc is fast but not nearly as fast as the RTS alloc functions;
> one thing I have not started is integrating the replacement library
> with GHC, mostly because the replacement library (on par or faster
> than GMP) uses SIMD functions whenever possible and they require
> proper alignment.
Ok, it's good to know you're already working on integrating a
(native) replacement library.
>> I also performed the test with the datatype suggested by John
>> Meacham (using a gmp library with renamed symbols),
>> > data FInteger = FInteger Int# (!ForeignPtr Mpz)
>> but it was around 8x slower, maybe due to the ForeignPtr and FFI
>> overhead, or due to missing optimizations in the code.
>
> That is quite an interesting result. Are these "safe" foreign
> imports?
No. Note that `FInteger' above is even faster than the build-in
Integer type for small integers (Ints), so I was talking about
allocation of gmp integers. I elaborated the test a little, it now
shows consistent results I think [1a]; a lot of performance is lost
when doing many allocations using malloc, and even more invoking
ForeignPtr finalizers.
I'm still interested in sensible solutions to Bug #311, and maybe
nevertheless simple switching to standard gmp allocation (either
with finalizers or copying limbs when entering/leaving the gmp) via a
compile flag would be the right thing for many applications.
I'm also looking forward to see the results of the replacement
library you're trying to integrate, and those of haskell Integer
implementations.
regards, benedikt
[1a] Integer Allocation Test
> allocTest :: Int -> `some Integral Type T'
> allocTest iterations = (iterateT iterations INIT) where
> iterateT 0 v = v
> iterateT k v = v `seq` iterateT (k-1) (v+STEP)
- Small BigNums Allocation Test (INIT = 2^31, STEP = 10^5, k=10^6)
Results (utime samples.sort[3..7].average) on darwin-i386 (dualcore):
0.04s destructive-update C implementation
0.19s with T = Integer
0.71s non-destructive-update C implementation using malloc
with T = FInteger {-# UNPACK -#} !Int# {-# UNPACK -#} !
(ForeignPtr Mpz)
0.90s with newForeignPtr_ (no finalizer, space leak)
1.87s with Foreign.Concurrent.newForeignPtr mpz do
{ hs_mpz_clear mpz; free mpz}
1.94s with newForeignPtr free_mpz_c_impl mpz
- Small Integers Allocation Test (INIT=0,STEP=4,k=2*10^8)
Results (utime samples.sort[3..7].average) on darwin-i386 (dualcore):
0.67s for Int
2.54s for FInteger
3.62s for Integer
More information about the Glasgow-haskell-users
mailing list