div_qr_1 interface

Torbjorn Granlund tg at gmplib.org
Thu Oct 17 19:26:23 CEST 2013


nisse at lysator.liu.se (Niels Möller) writes:

  nisse at lysator.liu.se (Niels Möller) writes:
  
  > To get going, I've written C implementations of mpn_div_qr_1n_pi1 and
  > mpn_divf_qr1n_pi1, and made divrem_1 call them.
  
  Below, also an mpn_div_qr_1, using these primitives (and with some
  inspiration from divrem_1). For return value, I use the type
  
    typedef struct { mp_limb_t r; mp_limb_t qh; } gmp_qr_1_t;
  
  The order here is a micro-optimization. I expect that on most ABI:s, for
  the typical code fragment
  
    gmp_qr_1_t res;
    ...
    res.r = mpn_foo (...);
    return res;
  
  the return value from mpn_foo will already be in the right register, and
  only qh needs to be moved from some callee-save register to the second
  return value register.
  
I am not too enthusiastic about struct return types for critical
functions.  I expect this to be returned via a stack slot everywhere o
almost everywhere.

But I agree that it is nice to avoid putting that extra quotient limb at
the main quotient operand.  Now, performance is more important than
cuteness...

  I also found some old x86_64 assembly code for the new div_qr_1
  algorithm. With perfect scheduling, it could run at 10 cycles on opteron
  (the main cpu of interest at the time). Main loop is 28 instructions,
  two independent mul, and decoder limited).
  
I recall to have seen some code for that.  How fast does it run
currently on the various CPUs?

Code comment:

I think we cannot afford to do a separate lshift of the dividend operand
when the divisor is just a few limbs.  We need to to shifting on-the-
fly, however irksome that might be.  AN mpn_div_qr_1u_pi1 is called-for.

-- 
Torbjörn


More information about the gmp-devel mailing list