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
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

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