3

I've been trying for days to install GMP library under MINGW. I have been using for weeks __uint128_t with gcc under a linux64 bit environment, then ported the same program under GMP and mingw (32 bit version). I used mpz_class integers instead of __uint128_t. Then I started my new program and...! With __uint128_t and 64 bit it takes 16 minutes to complete, with GMP and MINGW it takes 91 HOURS!!!

What should I do to speed up things a bit? Is there any faster way to do 128 bit integer math under a 32 bit environment? I don't need more than 128 bit, so is there any way to tell GMP "ok, I just need 128 bits, keep presicion fixed but please GO FASTER"?

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
Matteo Monti
  • 8,362
  • 19
  • 68
  • 114
  • What operations do you need to do on 128 bits? (`+`, `-`, `<`/`>`, `*`, `/`, something more interesting?) – osgx Aug 31 '11 at 22:15
  • 64-bit is supported natively by the compiler. Find code that does 64-bit arithmetic using 32-bit uints and use the principles to implement it for 128 bit uints using 64-bit uints. It'll not be as quick as native 128 bit support (which you might be able to get with e.g. SSE) but it'll probably be faster than libgmp. – user786653 Aug 31 '11 at 22:17
  • 64 bit may be supported by the compiler, but especially things like division (and modulo) and multiplication can be much faster in a real 64 bit environment (IOW, 64 bit registers, and more of them as well). – Rudy Velthuis Aug 31 '11 at 22:25

2 Answers2

3

No, when you are using an mpz_t, you can't limit GMP to fixed-len integers. mpz_t is a struct with lenght of limbs array (allocated; used) and a pointer to actual value which is stored as array of ints (limbs; array of int32 or int64). GMP is ready to expand length of any value when it will grow to big.

You can allocate 128 bits for every mpz_t at init, using mpz_init2:

 mpz_init2(mpz_t*, bit_number);

But the speedup from this is small, there is still data-indirection and length-handling.

You can use limbs directly with switching to mpn_ low-level functions:

http://www.gnu.org/software/gmp/manual/html_node/Low-level-Functions.html#Low-level%20Functions

There will be no pointer to limbs (this is good for cache), no easy input/output code; and no automatic limbs size handling (nor auto-expand; nor allocation). You should do all storage by yourself; may be even some carry must be handled manually, but there will be GMP's fast *, / and % operations; you can reconstruct mpz_t for easy input/output with mpz_t t;t._mp_size = t._mp_alloc=limb_number;t._mp_d=pointer_to_limb_array.

Also, you just can use uint128_t if you will switch to 64-bit mingw.

osgx
  • 90,338
  • 53
  • 357
  • 513
1

You can use MinGW-w64 instead, if the Windows machines you're targeting are new enough to ship with 64-bit Windows (e.g. Vista or 7).

michel-slm
  • 9,438
  • 3
  • 32
  • 31